简体   繁体   English

配置 TcpInboundGateway 以向同一消息发送多个响应

[英]Configuring a TcpInboundGateway to send multiple responses to the same message

I currently have a TcpInboundGateway that takes in messages, does some processing on the message and then returns the appropriate response, all as a TcpInboundGateway should.我目前有一个TcpInboundGateway接收消息,对消息进行一些处理,然后返回适当的响应,所有这些都是TcpInboundGateway应该的。

However, I am curious if this TcpInboundGateway can be configured in such a way that it will send an immediate response to the originating request but continue to process the request and send the post-processing response as well?但是,我很好奇这个TcpInboundGateway可以配置为它会立即向原始请求发送响应但继续处理请求并发送后处理响应?

Think of this immediate response as an acknowledgement to the sender that the message was received.将此立即响应视为对发送者收到消息的确认。

Possible Solution:可能的解决方案:

After reviewing this post , I came up with what I believe to be a viable solution to this problem.在查看了这篇文章之后,我想出了一个我认为可以解决这个问题的方法。

@Configuration
@EnableIntegration
public class Configuration {

    @Bean
    public AbstractServerConnectionFactory serverConnectionFactory() {
        return new TcpNetServerConnectionFactory(2002);
    }

    @Bean
    public TcpReceivingChannelAdapter inboundAdapter(AbstractServerConnectionFactory serverConnectionFactory) {
        TcpReceivingChannelAdapter inboundAdapter = new TcpReceivingChannelAdapter();
        inboundAdapter.setConnectionFactory(serverConnectionFactory);
        inboundAdapter.setOutputChannelName("sendAcknowledgement");
        return inboundAdapter;
    }

    @MessageEndpoint
    public class InboundMessageHandler {

        @Autowired
        private OutboundMessageGateway gateway;

        @ServiceActivator(inputChannel="sendAcknowledgement", outputChannel="doProcessing")
        public Message<String> initialAck(Message<String> message) {
            gateway.send("ACK", message.getHeaders().get(IpHeaders.CONNECTION_ID).toString());
            return message;
        }

        @ServiceActivator(inputChannel="doProcessing", outputChannel="sendResponse")
        public Message<String> mockDelay(Message<String> message) throws InterruptedException {
            return message;
        }
    }

    @MessagingGateway(defaultRequestChannel="sendResponse")
    public interface OutboundMessageGateway {
        void send(@Payload String message, @Header(IpHeaders.CONNECTION_ID) String connectionId);
    }

    @Bean
    @ServiceActivator(inputChannel="sendResponse")
    public TcpSendingMessageHandler outboundAdapter(AbstractServerConnectionFactory serverConnectionFactory) {
        TcpSendingMessageHandler outboundAdapter = new TcpSendingMessageHandler();
        outboundAdapter.setConnectionFactory(serverConnectionFactory);
        return outboundAdapter;
    }

}

For the use-case with the TcpInboundGateway and acking with later reply you need to use a PublishSubscribeChannel with an Executor injected to make a processing async.对于使用TcpInboundGateway并确认稍后回复的用例,您需要使用PublishSubscribeChannel和注入的Executor来进行异步处理。

The first subscriber should return some ack into the replyChannel header.第一个订阅者应该向replyChannel返回一些确认。 This way your TcpInboundGateway will perform request-reply and return that ack into the socket connected.这样,您的TcpInboundGateway将执行请求-回复并将该确认返回到连接的套接字中。

At the same time as you want, the second subscriber can perform desired logic and build the real reply later.在您想要的同时,第二个订阅者可以执行所需的逻辑并稍后构建真正的回复。 Only the point that we need to use the mention in the docs Collaborating Outbound and Inbound Channel Adapters (as you noticed already).只有我们需要使用文档Collaborating Outbound and Inbound Channel Adapters中提到的一点(正如您已经注意到的那样)。 So, since TcpInboundGateway populates an IpHeaders.CONNECTION_ID header into a request message, it is going to be available in your async process and subsequent TcpSendingMessageHandler will know where to send your processed reply:因此,由于TcpInboundGatewayIpHeaders.CONNECTION_ID header 填充到请求消息中,因此它将在您的异步过程中可用,随后TcpSendingMessageHandler将知道将处理后的回复发送到哪里:

private void handleMessageAsServer(Message<?> message) {
    // We don't own the connection, we are asynchronously replying
    String connectionId = message.getHeaders().get(IpHeaders.CONNECTION_ID, String.class);
    TcpConnection connection = null;
    if (connectionId != null) {
        connection = this.connections.get(connectionId);
    }
    if (connection != null) {
        try {
            connection.send(message);
        }

So, what you need is like this:所以,你需要的是这样的:

  1. a PublishSubscribeChannel with an executor for your TcpInboundGateway一个PublishSubscribeChannel executor器的TcpInboundGateway
  2. A simple handler to reply with an ack as a first subscriber一个简单的处理程序,以 ack 作为第一个订阅者进行回复
  3. A sub-flow for processing a request处理请求的子流程
  4. A TcpSendingMessageHandler to send a process response into the same TCP connection.一个TcpSendingMessageHandler将进程响应发送到同一个 TCP 连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM