【问题标题】:JMS: cannot select jms message from topic by selectorJMS:无法通过选择器从主题中选择 jms 消息
【发布时间】:2012-02-03 05:43:53
【问题描述】:

在按消息 ID 从主题中选择消息时遇到问题。 下面是精简的代码:

//publish message
connectionFactory = new ActiveMQConnectionFactory("vm://localhost"); 
//or external broker: tcp://localhost:61616

con = connectionFactory.createConnection();
con.setClientID("foo");
con.start();
session = connection.createSession(true, Session.SESSION_TRANSACTED);
topic = session.createTopic("topic_name");
producer = session.createProducer(topic);
//create text message
producer.send(message);
messageId = message.getJMSMessageID();
session.commit();
//close all stuff

//get message by id (the same VM split second after publishing)
//get connection the same way as for publishing
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
topic = session.createTopic("topic_name");
consumer = session.createDurableSubscriber(topic, "SUBS1", "JMSMessageID='messageId'", false);
//here we get stuck though the message IS there
msg = consumer.receive(); //receiveNoWait gives null

此外,即使我提供了始终正确的选择器 例如"1=1" 或空一:"", null

尽管它是持久订阅者,但它也不会获取消息。

另一方面,如果我在创建了始终为 true 选择器的消费者之后发布了某些内容,它确实会获取此消息。

但是这样的代码确实会获取我所有的消息,包括我一直在寻找的带有 id 的消息

consumer = session.createDurableSubscriber(topic, "SUBS1");
while (msg != null) {
    msg = consumer.receive();
}

在我看来,带有选择器的 DurableSubscriber 会忽略现有消息。虽然我在 jms 1.1 规范中没有找到类似的东西

到目前为止,我仅尝试将 ActiveMQ 5.5.1 作为 JMS 提供程序

问题是我做错了什么还是一个错误?

【问题讨论】:

    标签: java jms


    【解决方案1】:

    据我回忆,选择器的行为类似于 SQL,因此您需要确保您实际选择的是消息上的有效属性。

    尝试将您的选择器更改为 `"JMSMessageID='ID:'" 并查看是否有效。

    【讨论】:

    • 你是对的 jms 选择器类似于 SQL。我尝试了很多种:null、""、"1=1"、"true"、"JMSMessageID='ID:QWERTY...52-2:0:1:1:1'"、"JMSMessageID IN('ID :QWERTY...52-2:0:1:1:1','QWERTY...52-2:0:1:1:1')”。没有任何作用
    【解决方案2】:

    如果您在向某个主题发送消息“之后”连接到该主题(并且您确实这样做了),那么您将无法接收该消息。除非使用了持久订阅者并且它是在消息发送到主题“之前”创建的。

    只有活动的非持久订阅者和已创建的持久订阅者才会在主题中存储消息。即使他们处于离线状态。

    您可以使用选择器创建持久订阅者,该选择器使用特定的correlationId,然后将该correlationId 设置为您的消息并将其发送到主题。

    【讨论】:

      【解决方案3】:

      当消息传递提供者从生产者那里获得发布时,它会检查是否有任何与发布主题匹配的订阅。如果找到匹配的订阅,则将发布传递给这些订阅者。所以在发布消息之前必须先创建订阅。

      【讨论】:

      • 我想过。您为这个想法添加了 +1。换句话说,您无法通过 id 从主题获取消息。反正我已经不需要了。非常感谢。
      • 不过有一种方法,就是使用 Retain Publications。消息传递提供者能够缓存发布在主题上的消息。大多数提供者只缓存最后一个发布。因此,使用保留发布功能,订阅者进来时至少会获得最后一个发布,如果不是全部,那是之前发布的。
      猜你喜欢
      • 2012-09-08
      • 2011-08-27
      • 2015-06-16
      • 2015-11-05
      • 1970-01-01
      • 2021-04-17
      • 1970-01-01
      • 2016-05-07
      • 2013-08-09
      相关资源
      最近更新 更多