Rabbitmq 如何关联请求和;使用原始(不使用网关)Spring集成时的回复?

Rabbitmq 如何关联请求和;使用原始(不使用网关)Spring集成时的回复?,rabbitmq,messaging,spring-integration,eai,Rabbitmq,Messaging,Spring Integration,Eai,我正在学习Spring集成,并对网关和服务激活器有基本的了解。我喜欢网关的概念。SpringIntegration在运行时为网关生成代理。此代理对网关的使用者隐藏所有消息传递详细信息。此外,生成的代理还可能是与请求和应答相关的 出于学习的目的,我开始使用原始Spring集成特性而不是网关来实现请求和应答关联。我可以在请求头中设置相关标识符,但在接收通道的应答时无法指定相关标识符。下面(在问题的末尾)是同样的代码片段。还有,关联内容如何针对消息代理(例如RabbitMQ)工作?RabbitMQ是否

我正在学习Spring集成,并对网关和服务激活器有基本的了解。我喜欢网关的概念。SpringIntegration在运行时为网关生成代理。此代理对网关的使用者隐藏所有消息传递详细信息。此外,生成的代理还可能是与请求和应答相关的

出于学习的目的,我开始使用原始Spring集成特性而不是网关来实现请求和应答关联。我可以在请求头中设置相关标识符,但在接收通道的应答时无法指定相关标识符。下面(在问题的末尾)是同样的代码片段。还有,关联内容如何针对消息代理(例如RabbitMQ)工作?RabbitMQ是否能够检索包含特定头(相关标识符)的消息

公共类RemoteProxyCalculatorService实现CalculatorService
{
公共国际广场(国际北)
{
UUID UUID=SendRequest(n,“squareRequestChannel”);
int squareOfn=接收端(“squareReplyChannel”,uuid);
返回平方n;
}
专用UUID发送请求(T有效负载、字符串请求通道)
{
UUID requestID=UUID.randomUUID();
Message inputMessage=MessageBuilder.withPayload(有效负载)
.setCorrelationId(请求ID)
.build();
MessageChannel=(MessageChannel)context.getBean(requestChannel,MessageChannel.class);
信道发送(输入消息);
返回请求ID;
}
@抑制警告(“未选中”)
专用T接收器(字符串回复通道,UUID请求ID)
{
//如何使用requestID以便只接收与此线程发布的请求相关的回复
PollableChannel=(PollableChannel)context.getBean(replyChannel);
Message groupMessage=channel.receive();
return(T)groupMessage.getPayload();
}
私有类路径XmlApplicationContext上下文;
}

谢谢。

在应用程序中进行关联的最简单方法甚至不需要correlationId标题。相反,您可以创建一个QueueChannel实例(您不共享),并将其作为您发送的消息上的replyChannel头提供。无论下游组件最终响应什么,它都会在消息中找到该头

关于RabbitMQ,我们的出站网关只应用了类似的技术,但使用了AMQP消息的replyTo属性

希望有帮助


-Mark

问题在于公共回复频道。解决方案(马克建议的类似方案)如下所示

公共类RemoteProxyCalculatorService
{
公共国际广场(国际北)
{
PollableChannel replyChannel=SendRequest(n,“squareRequestChannel”);
int squareOfn=接收端(replyChannel);
返回平方n;
}
专用PollableChannel SendRequest(T有效负载、字符串请求通道)
{
UUID requestID=UUID.randomUUID();
QueueChannel replyQueueChannel=新的QueueChannel();
Message inputMessage=MessageBuilder.withPayload(有效负载)
.setCorrelationId(请求ID)
.setReplyChannel(replyQueueChannel)
.build();
MessageChannel=context.getBean(requestChannel,MessageChannel.class);
信道发送(输入消息);
返回replyQueueChannel;
}
@抑制警告(“未选中”)
private T Receiveply(可轮询频道回复频道)
{
Message groupMessage=replyChannel.receive();
return(T)groupMessage.getPayload();
}
私有类路径XmlApplicationContext上下文;
}

如果你想使用公共回复频道,我想这就是你想要的

公共类RemoteProxyCalculatorService
{
公共国际广场(国际北)
{
PollableChannel replyChannel=SendRequest(n,“squareRequestChannel”);
int squareOfn=接收端(replyChannel);
返回平方n;
}
专用PollableChannel SendRequest(T有效负载、字符串请求通道)
{
UUID requestID=UUID.randomUUID();
Message inputMessage=MessageBuilder.withPayload(有效负载)
.setCorrelationId(请求ID)
.setReplyChannel(myMessageHandler.getSubscribedChannel())
.build();
//为两件事创建一个可轮询的频道
//1.可轮询通道是此线程应查找回复的位置。
QueueChannel replyQueueChannel=新的QueueChannel();
//2.一旦消息处理程序使用相关Id接收到回复,它将向该可轮询通道发送回复。
添加(requestID,replyQueueChannel);
MessageChannel=context.getBean(requestChannel,MessageChannel.class);
信道发送(输入消息);
返回replyQueueChannel;
}
@抑制警告(“未选中”)
private T Receiveply(可轮询频道回复频道)
{
Message groupMessage=replyChannel.receive();
return(T)groupMessage.getPayload();
}
私有类路径XmlApplicationContext上下文;
@自动连线
私有MyMessageHandler MyMessageHandler;
}
/**
*消息处理程序
* 
*/
公共类MyMessageHandler实现MessageHandler
{
私有最终映射idChannelsMap=newtreemap();
私有最终对象锁=新对象();
专用最终订阅频道订阅频道;
公共MyMessageHandler(SubscribableChannel subscribedChannel)
{
this.subscribedChannel=subscribedChannel;
}
@凌驾
public void handleMessage(消息消息消息)引发MessaginException
{
已同步(锁定)
{
this.idChannelsMap.get(message.getHeaders().getCorrelationId()).send(message);
this.idChannelsMap.remove(message.getHeaders().getCorrelationId());
}
}
public void add(对象correlationId,MessageChannel MessageChannel)
{
已同步(锁定)
{
这个.idChannelsMap.put(correlationI
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;
}