This is a new question following up on this older question and answer (specifically the comment that says "don't comment on old answers, ask a new question"), as well as these examples in GitHub.
I know the answer and examples are minimal working "trivial examples", but I don't know enough about how "things work in Spring" (or should work) to understand how to decompose those generic, trivial examples into separate servers and clients that suit my purpose. I currently have a working Spring-Boot daemon application that is client to / calls on (without any "spring integration") a legacy daemon application over a TCP Socket connection. It's all working, running in production.
But now I am tasked with migrating the legacy daemon to Spring Boot too. So I only need to configure and set up a cached/pooled TCP connection "socket listener" on the server-side. However, the "client parts" of the existing (self contained) examples confuse me. In my case the "client side" (the existing Spring Boot daemon) is not going to change and is a separate app on a separate server, I only need to set up / configure the "server-side" of the socket connection (the "legacy-daemon freshly migrated to Spring Boot" daemon).
I've copied this example configuration (exactly) into my legacy-migration project
@EnableIntegration
@IntegrationComponentScan
@Configuration
public static class Config {
@Value(${some.port})
private int port;
@MessagingGateway(defaultRequestChannel="toTcp")
public interface Gateway {
String viaTcp(String in);
}
@Bean
@ServiceActivator(inputChannel="toTcp")
public MessageHandler tcpOutGate(AbstractClientConnectionFactory connectionFactory) {
TcpOutboundGateway gate = new TcpOutboundGateway();
gate.setConnectionFactory(connectionFactory);
gate.setOutputChannelName("resultToString");
return gate;
}
@Bean
public TcpInboundGateway tcpInGate(AbstractServerConnectionFactory connectionFactory) {
TcpInboundGateway inGate = new TcpInboundGateway();
inGate.setConnectionFactory(connectionFactory);
inGate.setRequestChannel(fromTcp());
return inGate;
}
@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) {
return in.toUpperCase();
}
@Transformer(inputChannel="resultToString")
public String convertResult(byte[] bytes) {
return new String(bytes);
}
}
@Bean
public AbstractClientConnectionFactory clientCF() {
return new TcpNetClientConnectionFactory("localhost", this.port);
}
@Bean
public AbstractServerConnectionFactory serverCF() {
return new TcpNetServerConnectionFactory(this.port);
}
}
...and the project will start on 'localhost' and "listen" on port 10000. But, when I connect to the socket from another local app and send some test text, nothing returns until I shut down the socket listening app. Only after the socket listening app starts shutting down does a response (the correct 'uppercased' result) go back to the sending app.
How do I get the "listener" to return a response to the "sender" normally, without shutting down the listener's server first?
Or can someone please provide an example that ONLY shows the server-side (hopefully annotation based) setup? (Or edit the example so the server and client are clearly decoupled?)