大家。我有一个HTTP API用于在RabbitMQ代理中发布消息,我需要实现请求 - 响应模式,以便从服务器接收响应。所以我就像是客户端和服务器之间的桥梁。我使用特定的路由密钥将消息推送到代理,并且有消息用于消息,它将按摩作为响应发布回来,我的API必须消耗每个请求的响应。所以图表是这样的:
所以我做的是以下内容 - 对于每个HTTP会话,我创建一个临时的responseQueue(绑定到默认交换,路由键是该队列的名称),之后我将消息的replyTo头设置为是响应队列的名称(我将等待响应),并将模板replyQueue设置为该队列。这是我的代码:
public void sendMessage(AbstractEvent objectToSend, final String routingKey) {
final Queue responseQueue = rabbitAdmin.declareQueue();
byte[] messageAsBytes = null;
try {
messageAsBytes = new ObjectMapper().writeValueAsBytes(objectToSend);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
MessageProperties properties = new MessageProperties();
properties.setHeader("ContentType", MessageBodyFormat.JSON);
properties.setReplyTo(responseQueue.getName());
requestTemplate.setReplyQueue(responseQueue);
Message message = new Message(messageAsBytes, properties);
Message receivedMessage = (Message)requestTemplate.convertSendAndReceive(routingKey, message);
}
那么问题是什么:消息被发送,之后它被消费者使用并且其响应被正确地发送到正确的队列,但由于某种原因它不会被回收在convertSendAndReceived方法中并且在集合之后timeout我的receivedMessage为null。所以我试着做了几件事 - 我开始检查弹簧代码(顺便说一下,这是一个真正的噩梦)并且看到我没有声明它为我创建一个时间的响应队列,以及replyTo头设置为队列的名称(与我的相同)。结果是相同的 - receivedMessage仍为null。之后我决定使用另一个使用默认交换的模板,因为responseQueue绑定到该交换:
requestTemplate.send(routingKey, message);
Message receivedMessage = receivingTemplate.receive(responseQueue.getName());
结果相同 - responseMessage仍然为null。 amqp和兔子的版本分别为1.2.1和1.2.0。所以我确信我会错过一些东西,但我不知道它是什么,所以如果有人可以帮助我,我将非常感激。
答案 0 :(得分:2)
1>如果您提供RabbitTemplate
,则doSendAndReceiveWithFixed
使用requestTemplate.setReplyQueue(responseQueue)
会很奇怪。看起来你的解释是假的。
2 - ;要使其与固定ReplyQueue
一起使用,您应配置reply
ListenerContainer
:
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(rabbitConnectionFactory);
container.setQueues(responseQueue);
container.setMessageListener(requestTemplate);
3>但这里最重要的部分是correlation
。 RabbitTemplate.sendAndReceive
填充correlationId
消息属性,但消费者方也必须处理它:仅仅发送回复responseQueue
,回复消息是不够的应具有相同的correlationId
属性。见这里:how to send response from consumer to producer to the particular request using Spring AMQP?
BTW没有理由手动填充Message
:您只需支持Jackson2JsonMessageConverter
RabbitTemplate
即可自动将objectToSend
转换为JSON字节有适当的标题。