【问题标题】:MQMessage exploring (using WebSphere MQ .NET API)MQMessage 探索(使用 WebSphere MQ .NET API)
【发布时间】:2010-12-21 13:42:09
【问题描述】:

我是 WebSphere MQ 的新手,但我有一个关于 MQMessage API 的问题。 看来 MQMessage 的接收者应该提前知道:

  • 写入的消息类型(如果是 WriteInt 然后是 ReadInt 等)
  • 属性名称和类型(如果 SetBooleanProperty(Name) 则 GetBooleanProperty(Name))

    这对我来说毫无意义。因为如果我不熟悉消息结构,我应该探索所有选项,直到我检索到其中的数据?

    我们将不胜感激, 伙计

  • 【问题讨论】:

      标签: .net api websphere ibm-mq mq


      【解决方案1】:

      是的,如果消息是固定长度的记录格式等结构化数据,你必须提前知道消息的格式才能解析它,这是绝对正确的。另一方面,如果消息负载被标记为数据结构(例如有效的 XML),那么您将使用普通解析来访问它。例如,您可能在不知道确切结构的情况下使用 XPath 访问 XML 有效负载。

      您提到的方法(WriteInt、ReadInt 等)通常用于从已知格式中提取数据并将缓冲区指针推进到下一个字段。但是,也有读写 UTF 字符串的方法。如果由于某种原因您的应用程序必须处理多种消息类型,那么您可以通过查询消息描述符来查询消息格式和消息类型。执行此操作的方法记录在 Message descriptor fields as properties 中。通过这种方式,您可以区分不同类型和格式的消息并进行适当的解析。

      请注意,我上面链接的文档是 v7 .Net 类。由于 v6 的生命周期结束是 2011 年 9 月,因此希望新的开发都与 v7 类有关,并且最好连接到 v7 QMgr。

      编辑 - 对 cme​​ts 的回应

      检查消息格式的示例:
      根据上面链接的页面,检查 C 头文件 cmqc.h 以获取 MQMD 中的字段。这将告诉您字段名称以及字段类型。在默认的 Windows 安装中,此文件位于 C:\Program Files\IBM\WebSphere MQ\tools\c\include\cmqc.h

      例如,message.getStringProperty('Root.MQMD.Format') 返回消息格式。在 cmqc.h 的顶部附近,您会发现一个名为 MQFMT_ 的宏列表,其中包含 MQMD 格式字段的可能值。从 v7.01 开始,它们看起来像这样:

       /* Formats */
       #define MQFMT_NONE               "        "
       #define MQFMT_ADMIN              "MQADMIN "
       #define MQFMT_CHANNEL_COMPLETED  "MQCHCOM "
       #define MQFMT_CICS               "MQCICS  "
       #define MQFMT_COMMAND_1          "MQCMD1  "
       #define MQFMT_COMMAND_2          "MQCMD2  "
       #define MQFMT_DEAD_LETTER_HEADER "MQDEAD  "
       #define MQFMT_DIST_HEADER        "MQHDIST "
       #define MQFMT_EMBEDDED_PCF       "MQHEPCF "
       #define MQFMT_EVENT              "MQEVENT "
       #define MQFMT_IMS                "MQIMS   "
       #define MQFMT_IMS_VAR_STRING     "MQIMSVS "
       #define MQFMT_MD_EXTENSION       "MQHMDE  "
       #define MQFMT_PCF                "MQPCF   "
       #define MQFMT_REF_MSG_HEADER     "MQHREF  "
       #define MQFMT_RF_HEADER          "MQHRF   "
       #define MQFMT_RF_HEADER_1        "MQHRF   "
       #define MQFMT_RF_HEADER_2        "MQHRF2  "
       #define MQFMT_STRING             "MQSTR   "
       #define MQFMT_TRIGGER            "MQTRIG  "
       #define MQFMT_WORK_INFO_HEADER   "MQHWIH  "
       #define MQFMT_XMIT_Q_HEADER      "MQXMIT  "
      

      实际的 MQMD 结构在 cmqc.h 的底部附近定义。从 v7.0.1 开始,它看起来像这样:

       /****************************************************************/
       /*  MQMD2 Structure -- Version-2 Message Descriptor             */
       /****************************************************************/
      
      
       typedef struct tagMQMD2 MQMD2;
       typedef MQMD2 MQPOINTER PMQMD2;
      
       struct tagMQMD2 {
         MQCHAR4   StrucId;           /* Structure identifier */
         MQLONG    Version;           /* Structure version number */
         MQLONG    Report;            /* Report options */
         MQLONG    MsgType;           /* Message type */
         MQLONG    Expiry;            /* Expiry time */
         MQLONG    Feedback;          /* Feedback or reason code */
         MQLONG    Encoding;          /* Numeric encoding of message data */
         MQLONG    CodedCharSetId;    /* Character set identifier of message
                                         data */
         MQCHAR8   Format;            /* Format name of message data */
         MQLONG    Priority;          /* Message priority */
         MQLONG    Persistence;       /* Message persistence */
         MQBYTE24  MsgId;             /* Message identifier */
         MQBYTE24  CorrelId;          /* Correlation identifier */
         MQLONG    BackoutCount;      /* Backout counter */
         MQCHAR48  ReplyToQ;          /* Name of reply-to queue */
         MQCHAR48  ReplyToQMgr;       /* Name of reply queue manager */
         MQCHAR12  UserIdentifier;    /* User identifier */
         MQBYTE32  AccountingToken;   /* Accounting token */
         MQCHAR32  ApplIdentityData;  /* Application data relating to
                                         identity */
         MQLONG    PutApplType;       /* Type of application that put the
                                         message */
         MQCHAR28  PutApplName;       /* Name of application that put the
                                         message */
         MQCHAR8   PutDate;           /* Date when message was put */
         MQCHAR8   PutTime;           /* Time when message was put */
         MQCHAR4   ApplOriginData;    /* Application data relating to
                                         origin */
         MQBYTE24  GroupId;           /* Group identifier */
         MQLONG    MsgSeqNumber;      /* Sequence number of logical message
                                         within group */
         MQLONG    Offset;            /* Offset of data in physical message
                                         from start of logical message */
         MQLONG    MsgFlags;          /* Message flags */
         MQLONG    OriginalLength;    /* Length of original message */
       };
      

      cmqc.h 文件为显示的每个字段定义了宏,这些宏将包含可能的值。这些宏也在 .Net 类中定义为 MQC 对象。 MQC is described here 但由于它没有方法,因此该页面仅将您引向它定义的 WMQ 常量列表。那个页面is here

      【讨论】:

      • @T.Rob -谢谢,但您能否详细说明您提到的“查询”方法?我阅读了 V7.0 规范,但仍然不了解 Inquire 方法(在所有类型的 MQ 对象上)以及它是如何工作的。如果您可以为此提供一个简短的代码 sn-p ,那将不胜感激。
      • @T.Rob 我阅读了更多关于它的信息,您可以使用:MQMessage 的 Format 和 MessageType 属性,而不是查询它们。我仍然不明白如何才能知道类型(或者我应该限制只使用 WriteUTF 和 ReadUTF)?那么消息属性呢?
      • @Guy - 我并不是要暗示这些属性有查询方法。您将使用适当的 message.get*Property 方法来获取任何 MQMD 属性。我已经用如何获取 MQMD.Format 属性和指向其他文档页面的指针的示例编辑了回复。希望对您有所帮助。
      • @T.Rob,谢谢,但是:message.Format 和 message.getStringProperty('Root.MQMD.Format') 之间有什么区别?如何获取有关消息包含的自定义属性的任何信息?它们的类型和名称?在 JMS 中,您有 Message.getPropertiesNames(),我可以在其中遍历所有消息属性。我在这里寻找类似的东西。我同意在 JMS 中您对属性类型有同样的问题,但您至少知道属性的名称。
      • @Guy - message.Format 和 message.getStringProperty('Root.MQMD.Format') 之间没有区别。我想通过一个直接可用的属性来说明 getStringProperty 的使用,以便您可以比较这两种方法。可以直接作为消息属性使用的字段数量有限,但可以通过其他方式访问任何消息或用户属性。要检索属性名称,请使用 MQMessage 的 public System.Collections.IEnumerator GetPropertyNames(String name) 方法。
      猜你喜欢
      • 2011-02-10
      • 2011-05-29
      • 1970-01-01
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 2010-10-28
      相关资源
      最近更新 更多