dplesa
dplesa

Reputation: 1415

Spring Integration TCP

I want to setup Spring TCP Server-Client application. I need a Server listening for incoming messages on a port, for example, 6666, and Client sending the messages on a different port, for example 7777. I have followed the documentation, but I'm stuck with the problem that the Client expects to receive a response, but in fact, the other end will just receive the messages from the Client and will not send any response. So, basically, I'm constantly getting this error:

o.s.i.ip.tcp.TcpOutboundGateway          : Tcp Gateway exception

org.springframework.integration.MessageTimeoutException: Timed out waiting for response

I found this answer to the similar question, so I tried to integrate the answer in my code. This is my Config class:

@EnableIntegration
@IntegrationComponentScan
@Configuration
public class Config {

private int port = 6666;

@MessagingGateway(defaultRequestChannel = "toTcp")
public interface Gateway {
    String viaTcp(String in);
}

@Bean
@ServiceActivator(inputChannel = "toTcp")
public TcpOutboundGateway tcpOutGate(AbstractClientConnectionFactory connectionFactory) {
    TcpOutboundGateway gate = new TcpOutboundGateway();
    gate.setConnectionFactory(connectionFactory);
    gate.setOutputChannelName("resultToString");
    gate.setRequiresReply(false);

   return gate;
}

@Bean
public TcpInboundGateway tcpInGate(AbstractServerConnectionFactory connectionFactory) {
    TcpInboundGateway inGate = new TcpInboundGateway();
    inGate.setConnectionFactory(connectionFactory);
    inGate.setRequestChannel(fromTcp());

    return inGate;
}

@Bean
public ByteArrayRawSerializer serializer() {
    return new ByteArrayRawSerializer();
}

@Bean
public MessageChannel fromTcp() {
    return new DirectChannel();
}

@MessageEndpoint
public static class Echo {

    @Transformer(inputChannel = "fromTcp", outputChannel = "toEcho")
    public String convert(byte[] bytes) {
        return new String(bytes);
    }

    @ServiceActivator(inputChannel = "toEcho")
    public String upCase(String in) {
        System.out.println("Server received: " + in);
        return in.toUpperCase();
    }

    @Transformer(inputChannel = "resultToString")
    public String convertResult(byte[] bytes) {
        return new String(bytes);
    }

}

@Bean
public AbstractClientConnectionFactory clientCF() {
    TcpNetClientConnectionFactory tcpNet = new TcpNetClientConnectionFactory("localhost", 7777);
    tcpNet.setDeserializer(serializer());
    tcpNet.setSerializer(serializer());
    tcpNet.setSingleUse(true);
    tcpNet.setTaskExecutor(new NullExecutor());
    return tcpNet;
}

@Bean
public AbstractServerConnectionFactory serverCF() {
    TcpNetServerConnectionFactory tcp = new TcpNetServerConnectionFactory(this.port);
    tcp.setSerializer(serializer());
    tcp.setDeserializer(serializer());
    return tcp;
}


public class NullExecutor implements Executor {

    public void execute(Runnable command) {}
}

}

This is how I use the Client to send the messages:

@Autowired
private Gateway gateway;
gateway.viaTcp("Some message");

How can I setup the Client so that it doesn't wait for the response?

Upvotes: 5

Views: 3522

Answers (1)

Gary Russell
Gary Russell

Reputation: 174494

See the reference manual.

Gateways are for request/reply interaction, channel adapters are for one-way interaction.

Use TcpSendingMessageHandler and TcpReceivingChannelAdapter instead of the inbound and outbound gateways.

Upvotes: 7

Related Questions