Chris Jansson
Chris Jansson

Reputation: 65

Returning Response from TCP Inbound Gateway

I'm stuck on a seemingly simple task, but am out of ideas. I have a TcpInboundGateway attached to a TcpNetServerConnectionFactory that passes requests to a Service Activator. The Service Activator simply puts the message back on the Gateway's reply channel. I want the Gateway to return that message over the connection.

When I run the test, the message makes it to the Service Activator successfully. I know this because the Service Activator prints the message payload before returning it. I also know the Service Activator is putting the message on the right channel because I have an interceptor on that channel which also prints the message.

The problem seems to be that the Gateway isn't reading off of that channel, even though I set it in setReplyChannel(). I can also see this in the logs:

Adding {bridge:null} as a subscriber to the 'testResponseChannel' channel

which makes me suspect that the message is just getting sent to the null channel instead of being picked up by my Gateway.

Here's the configuration:

    @Bean
    public TcpNetServerConnectionFactory testServerFactory() {
        TcpNetServerConnectionFactory testServerFactory = new TcpNetServerConnectionFactory(0);
        testServerFactory.setSerializer(TcpCodecs.lengthHeader2());
        testServerFactory.setDeserializer(TcpCodecs.lengthHeader2());
        return testServerFactory;
    }

    @Bean
    public DirectChannel testRequestChannel() {
        return new DirectChannel();
    }

    @Bean
    public DirectChannel testResponseChannel() {
        DirectChannel testResponseChannel = new DirectChannel();
        testResponseChannel.addInterceptor(channelInterceptor());
        return testResponseChannel;
    }

    @Bean
    public TcpInboundGateway gateway() {
        TcpInboundGateway gateway = new TcpInboundGateway();
        gateway.setConnectionFactory(testServerFactory());
        gateway.setRequestChannel(testRequestChannel());
        gateway.setReplyChannel(testResponseChannel());
        return gateway;
    }

    @Bean
    @ServiceActivator(inputChannel = "testRequestChannel", outputChannel = "testResponseChannel")
    public EchoHandler echoHandler() {
        return new EchoHandler();
    }

Here's my POJO Service Activator:

public class EchoHandler {

    public Message<String> echoMessage(Message<String> request) {
        System.out.println(request.getPayload());
        return request;
    }
}

And here's the error, which happens right after the message passes through the interceptor:

Unexpected message - no endpoint registered with connection interceptor: localhost:6060:59848:3c6c3cff-c697-4fc9-b4e3-9ea14508cec7 - GenericMessage [payload=byte[3], headers={ip_tcp_remotePort=6060, ip_connectionId=localhost:6060:59848:3c6c3cff-c697-4fc9-b4e3-9ea14508cec7, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, id=93c75664-54db-c93e-ab3a-3e06b1e4b626, ip_hostname=localhost, timestamp=1556828832645}]

Upvotes: 0

Views: 403

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121272

To react properly for the reply from the server, your client must be a request-response capable. For this purpose Spring Integration IP modules suggests a TcpOutboundGateway. This way a TcpListener is going to be registered on the TcpConnection and ready to parse and handle replies messages on the socket.

Upvotes: 1

Related Questions