Spring AMQP响应来自MessageListener的ReplyTo队列

时间:2016-02-03 14:30:49

标签: spring rabbitmq amqp

如果我异步收听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.????

}

3 个答案:

答案 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(对于临时回复队列来说不是必需的)。