【问题标题】:Get receipt confirmation from the listener in JMS从 JMS 中的侦听器获取收据确认
【发布时间】:2013-12-07 21:16:57
【问题描述】:

我正在使用 Spring JMS 和 ActiveMQ 将消息从发送者发送到使用 ActiveMQ 主题(发布/订阅)的多个侦听器。到目前为止,所有的监听器都可以接收到来自发送者的消息。但是我想添加一个功能,当特定的侦听器(例如侦听器 1)收到消息时,侦听器 1 将向发件人发送回执确认。我按照my old post 中的评论,在发送者中创建了一个TemporaryQueue,并在发送者和接收者中使用ReplyTo 来获取从侦听器到发送者的确认消息。

我的发件人类别是:

public class CustomerStatusSender {
    private JmsTemplate jmsTemplate;
    private Topic topic;

    public void setJmsTemplate(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    public void setTopic(Topic topic) {
        this.topic = topic;
    }

    public void simpleSend(final String customerStatusMessage) {
        jmsTemplate.send(topic, new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                TextMessage message = session.createTextMessage("hello world");
                message.setStringProperty("content", customerStatusMessage);
                message.setIntProperty("count", 10);
                //send acknowledge request to a listener via a tempQueue
                Destination tempQueue = session.createTemporaryQueue();
                message.setJMSCorrelationID("replyMessage");
                message.setJMSReplyTo(tempQueue);
                return message;
            }
        });
    }
}

发送者创建一个TemporaryQueue 供监听者发回确认消息。然后在其中一个侦听器中,我有以下代码将确认消息发送回发件人:

public class CustomerStatusListener implements SessionAwareMessageListener<Message> {
    public void onMessage(Message message, Session session) {
        if (message instanceof TextMessage) {
            try {
                System.out.println("Subscriber 1 got you! The message is: "
                        + message.getStringProperty("content"));
                //create a receipt confirmation message and send it back to the sender
                Message response = session.createMessage();
                response.setJMSCorrelationID(message.getJMSCorrelationID());
                response.setBooleanProperty("Ack", true);
                TemporaryQueue tempQueue = (TemporaryQueue) message.getJMSReplyTo();
                MessageProducer producer = session.createProducer(tempQueue);
                producer.send(tempQueue, response);
            } catch (JMSException ex) {
                throw new RuntimeException(ex);
            }
        } else {
            throw new IllegalArgumentException(
                    "Message must be of type TextMessage");
        }
    }
}

但是,我发现Listener类中的下面一行会报错:

TemporaryQueue tempQueue = (TemporaryQueue) message.getJMSReplyTo();
MessageProducer producer = session.createProducer(tempQueue);

异常错误说:

The destination temp-queue://ID:xyz-1385491-1:2:1 does not exist. 

那么这里有什么问题?我假设发送者创建的tempQueue 可用于同一个 JMS 会话中的侦听器。为什么调用message.getJMSReplyTo() 后的tempQueue 对象没有返回有效的TemporaryQueue

另一个问题是:我如何在发件人中收到确认消息?我应该在发送者中实现MessageListener 接口以便接收来自侦听器的确认吗?还是直接调用receive()方法同步接收?

感谢您的任何建议!

【问题讨论】:

  • 我会检查临时队列是否真的被创建了。转到ActiveMQ web console 看看发生了什么。
  • 我去了 ActiveMQ web admin web 控制台并检查了它。我没有在Queue 列下找到任何项目。 TemporaryQueue 应该属于 ActiveMQ 中的Queue 吗?
  • 我不确定使用 createTemproraryQueue() 创建的队列,但是以“dynamicQueues”开头的命名临时队列肯定会出现。查看this document 的“动态创建目的地”部分 - 也许它适用于您的项目

标签: java jms activemq spring-jms


【解决方案1】:

我最终使用了一个单独的 JMS 队列将确认消息从 listener-1 发送到发送者。由于某种原因,ActiveMQ 创建的temporaryQueue 在JMS 会话期间不可用。

【讨论】:

    【解决方案2】:

    如果您使用的是 spring-jms,为什么不直接使用 MessageListenerAdapter 作为您的监听器? - 他会处理 replyTo 的东西,你的听众可以是一个简单的 POJO。

    在任何情况下,您都不需要将其强制转换为临时队列;就听众而言,它只是一个目的地。

    查看MessageListenerAdapter` javadocs

    另外,您需要在发送端的临时队列上创建一个消费者,以接收回复。如果发送连接关闭,临时队列将消失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 2017-08-31
      • 1970-01-01
      相关资源
      最近更新 更多