title: Spring Integration - How to implement an asynchronous TCP Socket requests/responses over the same connection?
body: <p>I have a Python TCP Socket server service which:</p>
  
  <ul>
  <li>Allows only one client connection at time;</li>
  <li>Its inputstream/outputstream operates independently.</li>
  </ul>
  
  <p>On the other side, I have a Java Spring Boot client application using Spring Integration. My actual TCP Socket configurator
  implementation uses:</p>
  
  <pre><code>@MessagingGateway(defaultRequestChannel = REQUEST_CHANNEL, errorChannel = ERROR_CHANNEL)
  public interface ClientGtw {
      Future&lt;Response&gt; send(Request request);
  }
  
  @Bean
  @ServiceActivator(inputChannel = REQUEST_CHANNEL)
  public MessageHandler outboundGateway(TcpNioClientConnectionFactory connectionFactory) {
      TcpOutboundGateway gateway = new TcpOutboundGateway();
      gateway.setConnectionFactory(connectionFactory);
      gateway.setRequestTimeout(TimeUnit.SECONDS.toMillis(timeout));
      gateway.setRemoteTimeout(TimeUnit.SECONDS.toMillis(timeout));
      return gateway;
  }
  
  @Bean
  public TcpNioClientConnectionFactory clientConnectionFactory(AppConfig config) {    
      Host host = getHost(config);
  
      TcpNioClientConnectionFactory factory = new TcpNioClientConnectionFactory(host.name, host.port);
      factory.setSingleUse(false);
      factory.setSoTimeout((int) TimeUnit.SECONDS.toMillis(timeout));
  
      SerializerDeserializer sd = new SerializerDeserializer();
      factory.setDeserializer(sd);
      factory.setSerializer(sd);
      return factory;
  }
  </code></pre>
  
  <p>This actual approach works fine, however, when a request is sent it hangs the connection until a response is received. This is a problem due the fact that some times a request can get too much time to receive a response and the system has other requests incomming whose response can be achieved faster. I would like to send and receive as much as possible requests and responses independetly (decoupled between them). The object transported (serialized and deserialized) contains a key pair that can do the correct correlation.</p>
  
  <p><strong>TL;DR: How to implement an Asynchronous requests/responses over the same connection?</strong></p>
  
  <p><strong>The Spring TcpOutboundGateway javadoc mentions: Use a pair of outbound/inbound adapters for that use case.</strong></p>
  
  <p>So, in addition to the declaration above:</p>
  
  <p><strong>1st Attempt</strong></p>
  
  <pre><code>@Bean
  public TcpInboundGateway inboundGateway(AbstractServerConnectionFactory connectionFactory) {
      TcpInboundGateway gateway = new TcpInboundGateway();
      gateway.setConnectionFactory(connectionFactory);
      gateway.setRequestTimeout(TimeUnit.SECONDS.toMillis(timeout));
      return gateway;
  }
  
  @Bean
  public AbstractServerConnectionFactory serverFactory(AppConfig config) {
      Host host = getHost(config);
      AbstractServerConnectionFactory connectionFactory = new TcpNetServerConnectionFactory(host.port);
      connectionFactory.setSingleUse(true);
      connectionFactory.setSoTimeout(timeout);
      return connectionFactory;
  }
  </code></pre>
  
  <blockquote>
    <p>The requests are blocked until a response is delivered as before.</p>
  </blockquote>
  
  <p><strong>2nd Attempt</strong></p>
  
  <pre><code>@Bean
  public TcpInboundGateway inboundGateway(TcpNioClientConnectionFactory connectionFactory) {
      TcpInboundGateway gateway = new TcpInboundGateway();
      gateway.setConnectionFactory(connectionFactory);
      gateway.setRequestTimeout(TimeUnit.SECONDS.toMillis(timeout));
      gateway.setClientMode(true);
      return gateway;
  }
  </code></pre>
  
  <blockquote>
    <p>org.springframework.integration.ip.tcp.connection.TcpNioClientConnectionFactory may only be used by one inbound adapter</p>
  </blockquote>
  
  <p>Any clue?</p>