![](/img/trans.png)
[英]How to implement HTTP request/reply when the response comes from a rabbitMQ reply queue using Spring Integration DSL?
[英]How to correlate request & reply when using raw (not using Gateway) Spring Integration?
我正在學習Spring-Integration,並對Gateway和Service-Activators有基本的了解。 我喜歡Gateway的概念。 Spring Integration在運行時為網關生成代理。 此代理隱藏來自網關使用者的所有消息傳遞詳細信息。 此外,生成的代理也可能是共同關聯的請求和回復。
為了學習,我開始使用原始Spring Integration功能而不是使用Gateway來實現請求和回復關聯。 我能夠在請求標頭中設置相關標識符,但在接收通道的回復時無法指定相關標識符。 以下(在問題的最后)是相同的代碼片段。 另外,相關內容如何對消息代理(例如RabbitMQ)起作用? RabbitMQ是否能夠檢索具有特定標頭(相關標識符)的消息?
public class RemoteProxyCalculatorService implements CalculatorService
{
public int Square(int n)
{
UUID uuid = SendRequest(n, "squareRequestChannel");
int squareOfn = ReceiveReply("squareReplyChannel", uuid);
return squareOfn;
}
private <T> UUID SendRequest(T payload, String requestChannel)
{
UUID requestID = UUID.randomUUID();
Message<T> inputMessage = MessageBuilder.withPayload(payload)
.setCorrelationId(requestID)
.build();
MessageChannel channel = (MessageChannel)context.getBean(requestChannel, MessageChannel.class);
channel.send(inputMessage);
return requestID;
}
@SuppressWarnings("unchecked")
private <T> T ReceiveReply(String replyChannel, UUID requestID)
{
//How to consume requestID so as to receive only the reply related to the request posted by this thread
PollableChannel channel = (PollableChannel)context.getBean(replyChannel);
Message<?> groupMessage = channel.receive();
return (T)groupMessage.getPayload();
}
private ClassPathXmlApplicationContext context;
}
謝謝。
在應用程序中關聯的最簡單方法甚至不需要correlationId標頭。 相反,您可以創建一個QueueChannel實例(您不共享),並將其作為您發送的消息上的replyChannel標頭提供。 無論下游組件最終響應什么,它都會在Message中找到該標頭。
關於RabbitMQ,我們的出站網關只使用類似的技術,但使用AMQP消息的replyTo屬性。
希望有所幫助。
-標記
常見的回復渠道存在問題。 解決方案(Mark建議類似)將如下所示。
public class RemoteProxyCalculatorService
{
public int Square(int n)
{
PollableChannel replyChannel = SendRequest(n, "squareRequestChannel");
int squareOfn = ReceiveReply(replyChannel);
return squareOfn;
}
private <T> PollableChannel SendRequest(T payload, String requestChannel)
{
UUID requestID = UUID.randomUUID();
QueueChannel replyQueueChannel = new QueueChannel();
Message<T> inputMessage = MessageBuilder.withPayload(payload)
.setCorrelationId(requestID)
.setReplyChannel(replyQueueChannel)
.build();
MessageChannel channel = context.getBean(requestChannel, MessageChannel.class);
channel.send(inputMessage);
return replyQueueChannel;
}
@SuppressWarnings("unchecked")
private <T> T ReceiveReply(PollableChannel replyChannel)
{
Message<?> groupMessage = replyChannel.receive();
return (T) groupMessage.getPayload();
}
private ClassPathXmlApplicationContext context;
}
如果您想使用通用回復頻道,那么我認為這就是您要尋找的。
public class RemoteProxyCalculatorService
{
public int Square(int n)
{
PollableChannel replyChannel = SendRequest(n, "squareRequestChannel");
int squareOfn = ReceiveReply(replyChannel);
return squareOfn;
}
private <T> PollableChannel SendRequest(T payload, String requestChannel)
{
UUID requestID = UUID.randomUUID();
Message<T> inputMessage = MessageBuilder.withPayload(payload)
.setCorrelationId(requestID)
.setReplyChannel(myMessageHandler.getSubscribedChannel())
.build();
// Create a Pollable channel for two things
// 1. Pollable channel is where this thread should look for reply.
QueueChannel replyQueueChannel = new QueueChannel();
// 2. Message Handler will send reply to this Pollable channel once it receives the reply using correlation Id.
myMessageHandler.add(requestID, replyQueueChannel);
MessageChannel channel = context.getBean(requestChannel, MessageChannel.class);
channel.send(inputMessage);
return replyQueueChannel;
}
@SuppressWarnings("unchecked")
private <T> T ReceiveReply(PollableChannel replyChannel)
{
Message<?> groupMessage = replyChannel.receive();
return (T) groupMessage.getPayload();
}
private ClassPathXmlApplicationContext context;
@Autowired
private MyMessageHandler myMessageHandler;
}
/**
* Message Handler
*
*/
public class MyMessageHandler implements MessageHandler
{
private final Map<Object, MessageChannel> idChannelsMap = new TreeMap<>();
private final Object lock = new Object();
private final SubscribableChannel subscribedChannel;
public MyMessageHandler(SubscribableChannel subscribedChannel)
{
this.subscribedChannel = subscribedChannel;
}
@Override
public void handleMessage(Message<?> message) throws MessagingException
{
synchronized (lock)
{
this.idChannelsMap.get(message.getHeaders().getCorrelationId()).send(message);
this.idChannelsMap.remove(message.getHeaders().getCorrelationId());
}
}
public void add(Object correlationId, MessageChannel messageChannel)
{
synchronized (lock)
{
this.idChannelsMap.put(correlationId, messageChannel);
}
}
public SubscribableChannel getSubscribedChannel()
{
return subscribedChannel;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.