从 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.");
}