1
votes

Im trying to implement a tcp client that will connect to an existing server using spring integration. Being still new to the technology, I have followed the spring examples at https://github.com/spring-projects/spring-integration-samples.

I've managed to implement the simple case where the client connects to a server, then sends a request and then receives a response back from the server. However, due to the way in which our server is implemented, I now need to implement the following case: The client must connect to the server and wait for a request from the server, then respond with response data.

How do I implement this? It doesn't look like I can use a gateway on the client side anymore, as the gateway requires me to send a request before I can get any response data. I then considered configuring a service-activator with the reply-channel of the tcp-outbound-gateway as its input channel. However, no replies are received by the service implementation. It seems that the channel is only opened once I send the first request from the client. Currently I have the following:

Spring configuration:

<int-ip:tcp-connection-factory id="client"
                               type="client"
                               host="localhost"
                               port="12345"
                               single-use="false"
                               so-timeout="10000"
                               deserializer="javaSerializerDeserializer"
                               serializer="javaSerializerDeserializer" />
<bean id="javaSerializerDeserializer"
      class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer" />

<int-ip:tcp-outbound-gateway id="outGateway"
                             request-channel="input"
                             reply-channel="clientBytes2StringChannel"
                             connection-factory="client"
                             request-timeout="10000"
                             reply-timeout="10000" />

<int:object-to-string-transformer id="clientBytes2String"
                                  input-channel="clientBytes2StringChannel" />

<int:service-activator input-channel="clientBytes2StringChannel" ref="thinclientService" />
<bean id="thinclientService" class="tcp.service.ThinClientService" />

ThinClientService:

@Component
public class ThinClientService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThinClientService.class);

    public String receive(String recv) {
        LOGGER.info("*****************Recv: {}", recv);
        return "echo";
    }
}

Main method:

@SpringBootApplication
public class Application {
    public static void main(String args[]) throws Exception {
            GenericXmlApplicationContext context = new GenericXmlApplicationContext();
        context.load("classpath:META-INF/beans.xml");
        context.registerShutdownHook();
        context.refresh();

        System.out.println("Running test");

        SpringApplication.run(Application.class, args);
    }
}

How can I force this client to connect to my server, even though I do not want to send data?

1

1 Answers

1
votes

Managed to figure this out myself. I had to change the tcp-outbound-gateway into a tcp-inbound-gateway with client-mode="true". Only then will the service-activator receive the message sent from the server.

Updated bean config:

<int-ip:tcp-connection-factory id="client"
                               type="client"
                               host="localhost"
                               port="12345" single-use="false" so-timeout="10000" deserializer="javaSerializerDeserializer"
                               serializer="javaSerializerDeserializer" />
<bean id="javaSerializerDeserializer"
      class="org.springframework.integration.ip.tcp.serializer.ByteArrayLfSerializer" />

<int-ip:tcp-inbound-gateway id="outGateway"
                            request-channel="input"
                            connection-factory="client"
                            client-mode="true"
                            retry-interval="1000"
                            scheduler="reconnectScheduler" />

<bean id="reconnectScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler" />

<int:object-to-string-transformer id="clientBytes2String"
                                  input-channel="input" output-channel="responseString" />

<int:service-activator input-channel="responseString" ref="thinclientService" />
<bean id="thinclientService" class="tcp.service.ThinClientService" />