Я использую Spring JMS и ActiveMQ для отправки сообщения от отправителя нескольким слушателям с использованием темы ActiveMQ (публикация/подписка). Пока все слушатели могут получать сообщение от отправителя. Но я хочу добавить функциональность, которая, когда конкретный слушатель, скажем, listener1, получает сообщение, listener1 отправит подтверждение квитанции отправителю. Я последовал за комментарием в 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. Почему объект tempQueue
после звонка message.getJMSReplyTo()
не возвращает действительный TemporaryQueue
?
Другой вопрос: Как получить сообщение подтверждения в отправителе? Должен ли я реализовать интерфейс MessageListener
в отправителе, чтобы получить подтверждение от слушателя? Или мне нужно просто вызвать метод для его синхронного приема?
Спасибо за любые предложения!
Я бы проверял, что очередь temp действительно создается. Перейдите в [ActiveMQ веб-консоль] (http://activemq.apache.org/web-console.html) и посмотрите, что происходит. – dimoniy
Я пошел в веб-консоль веб-администратора ActiveMQ и проверил его. Я не нашел элементов в столбце «Queue». Должен ли 'TemporaryQueue' принадлежать' Queue' в ActiveMQ? – tonga
Я не уверен в очередях, созданных с помощью createTemproraryQueue(), но имена тех времен, которые только начинаются с «dynamicQueues», определенно появляются. Отметьте раздел «Динамическое создание адресатов» в [этом документе] (http://activemq.apache.org/jndi-support.html) - возможно, он будет работать для вашего проекта – dimoniy