如果我异步收听Spring AMQP消息,如何使用发件人提供的ReplyTo队列和关联ID进行响应?
@Override
public void onMessage(Message message) {
byte[] bytes = message.getBody();
String body = new String (bytes);
logger.info(application + " processing message: \n" + body);
//some business logic
//now I want to respond to the replyto queue with the correlation ID
//rabbitTemplate.????
}
答案 0 :(得分:0)
我找到的一个解决方法是扩展ChannelAwareMessageListener并按如下方式构建响应
@Override
public void onMessage(Message message, Channel channel) {
String body = new String (message.getBody());
String correlationId = new String (message.getMessageProperties().getCorrelationId());
String replyTo = new String (message.getMessageProperties().getReplyTo());
logger.info("Processing message with Correlation ID : "
+ correlationId + " Replying To: " + replyTo + " and Message: \n"
+ body);
BasicProperties basicProperties = new BasicProperties
.Builder()
.correlationId(correlationId)
.contentType(MediaType.APPLICATION_JSON.getType())
.contentEncoding(StandardCharsets.UTF_8.name())
.build();
String response = "{\"response\":" + body + "}";
try {
channel.basicPublish( "", replyTo, basicProperties, response.getBytes());
} catch (IOException e) {
logger.error("Failed to send message: \n" + e.getMessage());
}
logger.info("Processed Message");
}
这样可以正常工作,但如果我可以使用RabbitMQTemplate进行类似的响应,那将会很棒。
答案 1 :(得分:0)
您只需致电AmqpTemplate.send(routingKey, message)。
作为路由键,使用 reply-to 值。模板将发布到默认交换并将消息路由到指定为路由密钥的队列(这是您的回复队列)。
此外,如果对方正在执行请求响应,您可能需要设置关联ID ,因此响应可以与请求匹配。
答案 2 :(得分:0)
根据有用的反馈,这里是使用Spring Messaging的等效解决方案:
public void onMessage(Message message) {
//mock response body
String body = "{ \"processing\": \"123456789\"}";
//mock response properties
MessageProperties properties = new MessageProperties();
properties.setContentType(MediaType.APPLICATION_JSON.toString());
properties.setContentEncoding(StandardCharsets.UTF_8.name());
//return the Correlation ID if present
if (message.getMessageProperties().getCorrelationId() != null) {
properties.setCorrelationId(message.getMessageProperties().getCorrelationId());
}
//create and return the response message
Message responseMessage = new Message(body.getBytes(), properties);
rabbitTemplate.send(message.getMessageProperties().getReplyTo(), responseMessage);
logger.info("Processed and returned message");
}
AMQP新手的一个令人困惑的部分是知道回复消息属性是"路由密钥"回复时的值(send或convertAndSend方法)。并且在默认交换中创建临时队列。永久回复队列并不总是如此,这需要一个correlation-id(对于临时回复队列来说不是必需的)。