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

时间:2015-06-17 13:55:54

标签: c# ibm-mq

使用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(...)将失败。这是我在使用主题时也会发现的行为。

我的问题是:

当发送到不存在的主题时,怎么没有出现问题? 我的配置部分错了吗? 是否有其他方法来验证主题是否确实存在?

2 个答案:

答案 0 :(得分:2)

  

如果发送到没有的主题,怎么会出现问题   存在?

因为您向主题发送消息或订阅主题的那一刻它就存在了。队列管理器会为您自动生成它。

根据JMS 2.1规范:

  

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

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

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

Produce
   Fruits
      Apple
      Banana
      Cranberry
   Vegetables
      Asparagus
      Beet
      Celery

如果您define a topic Fruits并将其指向主题字符串Produce/Fruits,则可以授权人们从Produce / Fruits中向下发布或订阅主题树的部分。拥有授权的人将无法访问Produce/Vegetables,除非您通过指向该主题对象的主题对象提供访问权限。

通常,最好在主题树的特定级别定义主题对象。如您所见,在Produce定义主题对象可授予对整个主题树的访问权限,但您只需要一个主题对象。在第二级定义对象,您需要两个覆盖树(一个在Fruits,一个在Vegetables),但在安全模型中具有更多粒度。在第三级定义主题,您具有极端的粒度,但还有更多的主题对象需要管理。

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

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

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

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

在连接工厂中指定主题对象时,该对象必须存在。指定主题字符串,如果您有权使用该字符串,MQ将自动为您自动生成。

我猜您正在使用的ID具有管理员权限,或者已被授予Produce/Fruits/Produce/Fruits的访问权限,因为您可以完全发布。因此,您将不会收到您发布的任何主题字符串的任何错误。

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

答案 1 :(得分:0)

您是否运行了用于.NET的" IBM消息服务客户端"安装程序?

XMS : XmsFactoryFactory moans about missing IBM.XMS.Impl

这是关于SO的另一个有用的帖子:

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