C# 如果将消息发送到不存在的主题,则不会引发错误

C# 如果将消息发送到不存在的主题,则不会引发错误,c#,ibm-mq,C#,Ibm Mq,使用IBM.XMS向不存在的主题发送消息时,不会引发异常。在对队列进行相同操作时,我会收到通知,队列管理器或队列不存在 以下是我创建连接并向主题发送消息的方式: XMSFactoryFactory xmsFactoryFactory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ); IConnectionFactory ibmConnectionFactory = xmsFactoryFactory.CreateConnectionFactory();

使用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”安装程序

以下是另一篇关于SO的有用帖子:

为什么当发送到一个没有问题的主题时不会出现问题 存在

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

根据JMS 2.1规范:

有些产品要求使用静态方式定义主题 关联的授权控制列表等;其他人甚至没有 有话题管理的概念

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

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

Produce
   Fruits
      Apple
      Banana
      Cranberry
   Vegetables
      Asparagus
      Beet
      Celery
如果您将其指向主题字符串
product/Fruits
,则可以授权用户从product/Fruits开始发布或订阅主题树的部分。拥有授权的人将无法访问
农产品/蔬菜
,除非您通过指向那里的主题对象为他们提供访问权限

通常,最好在主题树的某个级别定义主题对象。如上所述,在
product
中定义主题对象可以访问整个主题树,但您只需要一个主题对象。在第二级定义对象,您需要两个对象来覆盖树(一个位于
水果
,一个位于
蔬菜
),但在安全模型中具有更大的粒度。在第三个级别定义主题,您具有极高的粒度,但还需要管理更多的主题对象

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

如果定义一个名为
水果
的主题,并将其指向主题字符串
产品/水果
,则在打开该主题时有两种选择。如果打开主题对象,这将导致IBM MQ替换对象指向的主题字符串。您也可以直接打开主题字符串。由于IBM MQ始终基于最终主题字符串进行授权,因此这两种方法都会产生相同的有效授权

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

如果检查IBM MQ发布/订阅API或主题连接工厂的IBM实现,您将看到其中包含两个字段,一个用于主题对象,另一个用于主题字符串

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

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


有关IBM MQ如何管理主题的一般背景信息,请参见手册中的页面。

谢谢您的回答。客户端安装完成,所有程序集都可用。第二个链接看起来与另一个库有关,但我将研究它!哇,谢谢你的回答。我从qm.ini中删除了身份验证,所以我想这会有一些影响。是的,会的。请注意,一旦禁用OAM,就永远无法再次打开它。您必须从头开始删除并重新创建QMgr,然后重新构建所有对象,然后才能可靠地再次使用MQ授权。太棒了@罗布。谢谢。