2013-11-22 83 views
0

我正在使用Spring JMS和ActiveMQ使用ActiveMQ主題(發佈/訂閱)從發件人向多個收聽者發送消息。到目前爲止,所有聽衆都可以收到發件人發來的消息。但是我想添加一個功能,當一個特定的監聽者(比如listener1)獲得這個消息時,監聽者1會向發送者發送一個收據確認。我遵循my old post中的註釋,並在發件人中創建了TemporaryQueue,並在發件人和收件人中使用ReplyTo從收聽者處向發件人獲取確認消息。在JMS中收聽收聽確認

我的發件人類是:

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"); 
     } 
    } 
} 

然而,我發現,在監聽器類中的以下行引發錯誤:

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界面以便接收來自聽衆的確認?或者我應該撥打方法同步接收它?

感謝您的任何建議!

+0

我會檢查臨時隊列是否真的被創建。轉到[ActiveMQ Web控制檯](http://activemq.apache.org/web-console.html),看看發生了什麼。 – dimoniy

+0

我去了ActiveMQ的Web管理Web控制檯,並檢查它。我沒有在'Queue'列中找到任何項目。 ActiveMQ中'TemporaryQueue'屬於'Queue'嗎? – tonga

+0

我不確定使用createTemproraryQueue()創建的隊列,但命名爲剛剛以「dynamicQueues」開頭的臨時隊列肯定會顯示出來。查看[本文檔](http://activemq.apache.org/jndi-support.html)的「動態創建目的地」部分 - 也許它適用於您的項目 – dimoniy

回答

0

如果您使用spring-jms,爲什麼不使用MessageListenerAdapter作爲您的聽衆? - 他會照顧replyTo的東西,你的聽衆可以是一個簡單的POJO。在任何情況下,你都不需要將它轉換爲Tempoarary隊列;就聽衆而言,它只是一個目的地。

結帳的MessageListenerAdapter` javadocs

此外,您需要在發送端的臨時隊列上創建一個使用者,以接收答覆。如果發送連接已關閉,則臨時隊列將消失。

0

我結束了使用一個單獨的JMS隊列發送確認消息從偵聽器1到發件人。出於某種原因,ActiveMQ創建的temporaryQueue在JMS會話期間不可用。