如果将消息发送到不存在的主题,则不会抛出错误

No error thrown if message is sent to a non-existent topic

当使用 IBM.XMS 向不存在的主题发送消息时,不会抛出异常。当尝试对队列进行相同操作时,我收到队列管理器或队列不存在的通知。

这是我创建连接并向主题发送消息的方式:

XMSFactoryFactory xmsFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory ibmConnectionFactory = xmsFactoryFactory.CreateConnectionFactory();
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "frimasrv");
ibmConnectionFactory.SetIntProperty(XMSC.WMQ_PORT, 1415);
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_CHANNEL, "CH1");
ibmConnectionFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
ibmConnectionFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "API");

IConnection connection = ibmConnectionFactory.CreateConnection();
connection.ClientID = "client id";
ISession session = connection.CreateSession(false, AcknowledgeMode.AutoAcknowledge);

IDestination destination = session.CreateTopic("this.does.not.exist");
IMessageProducer producer = session.CreateProducer(destination);
IMessageConsumer durableConsumer = session.CreateDurableSubscriber(destination, "subscriptionName");

IMessage myMessage = session.CreateTextMessage("text");
producer.Send(myMessage);

用session.CreateQueue(...)补充session.CreateTopic(...)的调用,session.CreateProducer(...)会失败。这是我在使用主题时也期望的行为。

我的问题是:

为什么发送到一个不存在的主题却没有问题? 我的部分配置错误吗? 是否有其他方法可以验证主题是否确实存在?

你有运行 "IBM Message Service Client for .NET" 安装程序吗?

XMS : XmsFactoryFactory moans about missing IBM.XMS.Impl

这是另一个有用的 post SO:

How do I get Websphere MQ connection status and how do I reset the connection:

How come that no problems arise when sending to a topic that does not exist?

因为当您向主题发送消息或订阅主题时,它就存在了。队列管理器会自动为您激活它。

根据 JMS 2.1 规范:

Some products require that topics be statically defined with associated authorization control lists, and so on; others don’t even have the concept of topic administration.

IBM MQ 是不需要静态定义主题的产品之一。

您可能误解了 IBM MQ 对主题对象的使用。它们不定义主题本身,而是提供指向主题层次结构中应用访问控制列表的位置的指针。例如,考虑以下主题层次结构:

Produce
   Fruits
      Apple
      Banana
      Cranberry
   Vegetables
      Asparagus
      Beet
      Celery

如果您 define a topic Fruits 并将其指向主题字符串 Produce/Fruits 然后您可以授权人们发布或订阅来自 [=75= 的主题树部分] 上下来。拥有授权的人将无法访问 Produce/Vegetables,除非您通过指向那里的主题对象向他们提供访问权限。

通常,最好在主题树的某个级别定义主题对象。正如您在上面看到的,在 Produce 处定义一个主题对象可以授予对整个主题树的访问权限,但您只需要一个主题对象。在第二层定义对象,您需要两个来覆盖树(一个在 Fruits 和一个在 Vegetables),但在安全模型中有更多的粒度。在第三层定义主题,您将拥有极高的粒度,但也有更多的主题对象需要管理。

IBM MQ 定义了默认主题对象 SYSTEM.BASE.TOPIC,它指向全局主题 space 的根。任何有权访问 SYSTEM.BASE.TOPIC 的人都可以访问任何主题。默认情况下,这仅包括 MQ 管理员。

如果您定义一个名为 Fruits 的主题并将其指向主题字符串 Produce/Fruits,那么当您想要打开该主题时,您有两种选择。如果您打开主题 object,这会导致 IBM MQ 替换对象指向的主题 string。也可以直接打开话题string。由于 IBM MQ 始终根据最终主题字符串进行授权,因此这两种方法都会产生相同的有效授权。

如果您同时指定主题对象 主题字符串,则已定义对象中的主题字符串将用作您提供的字符串的前缀。将两者连接起来生成完整的主题字符串。例如,如果您同时指定主题对象 Fruits(在上例中指向字符串 Produce/Fruits 字符串 Produce/Fruits,MQ 连接这些并激活一个名为 Produce/Fruits/Produce/Fruits 的主题。尽量不要那样做。如果您确实需要这样做,请确保您了解 Combining topic strings 页面中描述的机制。

如果您检查 IBM MQ Pub/Sub API 或主题连接工厂的 IBM 实现,您将看到它们包含两个字段,一个用于主题对象,一个用于主题字符串.

当您在连接工厂中指定主题对象时,该对象必须存在。指定一个主题 string,如果您有权使用该字符串,MQ 将自动为您激活它。

我猜您使用的 ID 具有管理员权限或已被授予访问 SYSTEM.BASE.TOPIC 的权限,因为您完全可以发布。因此,对于您发布的任何主题字符串,您都不会收到任何错误。

另请参阅手册中的 Topic Strings 页面,了解 IBM MQ 如何管理主题的一般背景。