我目前有一个TcpInboundGateway
接收消息,对该消息进行一些处理,然后返回适当的响应,所有操作均应作为TcpInboundGateway
进行。
但是,我很好奇是否可以将TcpInboundGateway
配置为将发送对原始请求的立即响应但继续处理请求并发送后处理响应的方式吗?
可以将此立即响应视为对发件人的确认,即已收到该消息。
可能的解决方案:
在回顾了此post之后,我提出了我认为可以解决该问题的可行方案。
@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;
}
}
最佳答案
对于带有TcpInboundGateway
的用例,并在稍后的答复中回复,您需要使用注入了PublishSubscribeChannel
的Executor
进行处理异步。
第一个订阅者应在replyChannel
标头中返回一些确认。这样,您的TcpInboundGateway
将执行请求答复并将该确认返回到连接的套接字中。
在您希望的同时,第二个订户可以执行所需的逻辑并在以后建立真实的答复。我们只需要在文档Collaborating Outbound and Inbound Channel Adapters中使用提及这一点(您已经注意到)。因此,由于TcpInboundGateway
将IpHeaders.CONNECTION_ID
标头填充到请求消息中,因此它将在您的异步过程中可用,随后的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);
}
因此,您需要的是这样的:
PublishSubscribeChannel
的executor
和TcpInboundGateway
一个简单的处理程序,以第一位订阅者的身分回覆
用于处理请求的子流
TcpSendingMessageHandler
将进程响应发送到同一TCP连接中。