从 C# 获取 IBM MQ 消息后如何识别消息数据类型?是Object还是String类型?
From C# after getting IBM MQ message how to identify message data type? Is it Object or String type?
在我们公司,我们使用 IBM MQ 服务器进行消息队列。对于同一个队列,我们在方法 WriteObject 和 WriteString 的帮助下同时放置 String 和 Object 类型的数据消息。
问题出现在队列消费(读取消息)的时候。由于 Get 数据可以是 Object 或 String,我们需要决定在 MQMessage 实例上使用 ReadString 或 ReadObject 的方法。我做了解决方法,比如首先使用 ReadObject 方法,如果发生异常,然后使用 ReadString 尝试。
我不喜欢这个解决方法,有没有什么方法可以在调用 MQQueue 实例的 Get 方法后识别消息数据类型?
您可以在下面找到我的解决方法:
public object GetMessage(string queueName) {
MQQueueManager queueManager = new MQQueueManager("queueManagerName", "channel", "connection");
MQGetMessageOptions queueGetMessageOptions = new MQGetMessageOptions();
queueGetMessageOptions.Options = MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQPMO_SYNCPOINT;
try {
queueRead = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
queueMessage = new MQMessage();
queueMessage.Format = MQC.MQFMT_STRING;
queueRead.Get(queueMessage, queueGetMessageOptions);
try {
var readObject = queueMessage.ReadObject();
return readObject;
} catch (SerializationException) { } // if message in queue not a object
queueMessage.DataOffset = 0;
var stringMsg = queueMessage.ReadString(queueMessage.MessageLength);
return stringMsg;
} catch (MQException exp) {
if (exp.ReasonCode != 2033) {
log.ErrorFormat("MQException: ResonCode: {0}, {1}", exp.ReasonCode, exp.Message);
}
}
return "";
}
多么糟糕的设计。
首先,为什么要将两种不同的消息类型放入同一队列?糟糕,非常糟糕的主意。您应该使用 2 个不同的队列。什么,有人认为排队很稀少吗?你应该像糖果一样分发队列。
其次,如果您确实需要使用此设计,那么您应该阅读 MQMD structure 上的 MQ 知识中心。它包含一个名为 'Message Type' 的字段。大多数应用程序使用 'Message Type' 来包含 'MQMT_DATAGRAM' 或 'MQMT_REQUEST',但您可以设置自己的以 'MQMT_APPL_FIRST'.
开头的值
所以,定义几个常量:
public const int MY_MSG_OBJECT = MQC.MQMT_APPL_FIRST + 1;
public const int MY_MSG_STRING = MQC.MQMT_APPL_FIRST + 2;
因此,发送字符串消息的发送应用程序将执行:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_STRING;
sendmsg.MessageType = MY_MSG_STRING;
sendmsg.WriteString("This is a test message");
queue.Put(sendmsg, pmo);
发送对象消息的发送应用程序会做:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_NONE;
sendmsg.MessageType = MY_MSG_OBJECT;
sendmsg.WriteObject(someObject);
queue.Put(sendmsg, pmo);
接收应用程序会做:
MQMessage rcvmsg = new MQMessage();
queue.Get(rcvmsg, gmo);
// Check the Message Type
if (rcvmsg.MessageType == MY_MSG_STRING)
{
readString = queue.ReadString();
}
else if (rcvmsg.MessageType == MY_MSG_OBJECT)
{
readObject = queue.ReadObject();
}
else
{
System.Console.Out.WriteLine("Error: Unknown message type.");
}
在我们公司,我们使用 IBM MQ 服务器进行消息队列。对于同一个队列,我们在方法 WriteObject 和 WriteString 的帮助下同时放置 String 和 Object 类型的数据消息。
问题出现在队列消费(读取消息)的时候。由于 Get 数据可以是 Object 或 String,我们需要决定在 MQMessage 实例上使用 ReadString 或 ReadObject 的方法。我做了解决方法,比如首先使用 ReadObject 方法,如果发生异常,然后使用 ReadString 尝试。
我不喜欢这个解决方法,有没有什么方法可以在调用 MQQueue 实例的 Get 方法后识别消息数据类型?
您可以在下面找到我的解决方法:
public object GetMessage(string queueName) {
MQQueueManager queueManager = new MQQueueManager("queueManagerName", "channel", "connection");
MQGetMessageOptions queueGetMessageOptions = new MQGetMessageOptions();
queueGetMessageOptions.Options = MQC.MQGMO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING + MQC.MQPMO_SYNCPOINT;
try {
queueRead = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING);
queueMessage = new MQMessage();
queueMessage.Format = MQC.MQFMT_STRING;
queueRead.Get(queueMessage, queueGetMessageOptions);
try {
var readObject = queueMessage.ReadObject();
return readObject;
} catch (SerializationException) { } // if message in queue not a object
queueMessage.DataOffset = 0;
var stringMsg = queueMessage.ReadString(queueMessage.MessageLength);
return stringMsg;
} catch (MQException exp) {
if (exp.ReasonCode != 2033) {
log.ErrorFormat("MQException: ResonCode: {0}, {1}", exp.ReasonCode, exp.Message);
}
}
return "";
}
多么糟糕的设计。
首先,为什么要将两种不同的消息类型放入同一队列?糟糕,非常糟糕的主意。您应该使用 2 个不同的队列。什么,有人认为排队很稀少吗?你应该像糖果一样分发队列。
其次,如果您确实需要使用此设计,那么您应该阅读 MQMD structure 上的 MQ 知识中心。它包含一个名为 'Message Type' 的字段。大多数应用程序使用 'Message Type' 来包含 'MQMT_DATAGRAM' 或 'MQMT_REQUEST',但您可以设置自己的以 'MQMT_APPL_FIRST'.
开头的值所以,定义几个常量:
public const int MY_MSG_OBJECT = MQC.MQMT_APPL_FIRST + 1;
public const int MY_MSG_STRING = MQC.MQMT_APPL_FIRST + 2;
因此,发送字符串消息的发送应用程序将执行:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_STRING;
sendmsg.MessageType = MY_MSG_STRING;
sendmsg.WriteString("This is a test message");
queue.Put(sendmsg, pmo);
发送对象消息的发送应用程序会做:
MQMessage sendmsg = new MQMessage();
sendmsg.Format = MQC.MQFMT_NONE;
sendmsg.MessageType = MY_MSG_OBJECT;
sendmsg.WriteObject(someObject);
queue.Put(sendmsg, pmo);
接收应用程序会做:
MQMessage rcvmsg = new MQMessage();
queue.Get(rcvmsg, gmo);
// Check the Message Type
if (rcvmsg.MessageType == MY_MSG_STRING)
{
readString = queue.ReadString();
}
else if (rcvmsg.MessageType == MY_MSG_OBJECT)
{
readObject = queue.ReadObject();
}
else
{
System.Console.Out.WriteLine("Error: Unknown message type.");
}