Java – Spring Boot TCP client

Spring Boot TCP client… here is a solution to the problem.

Spring Boot TCP client

I’m looking for an example of connecting TCP via sping boot without xml (spring-integration).

I How to create a Tcp Connection in spring boot to accept connections? Get the following snippet URL.

In this example, the main method alone is sufficient to connect TCP. Why declare other beans and converters here?

Wrong? I don’t want to use a simple Java socket client to accept responses, but want to integrate with Spring. But there are no suitable examples to use Java DSL.

Can you help?

package com.example;

import java.net.Socket;

import javax.net.SocketFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.transformer.ObjectToStringTransformer;
import org.springframework.messaging.MessageChannel;

@SpringBootApplication
public class So39290834Application {

public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So39290834Application.class, args);
        Socket socket = SocketFactory.getDefault().createSocket("localhost", 9999);
        socket.getOutputStream().write("foo\r\n".getBytes());
        socket.close();
        Thread.sleep(1000);
        context.close();
    }

@Bean
    public TcpNetServerConnectionFactory cf() {
        return new TcpNetServerConnectionFactory(9999);
    }

@Bean
    public TcpReceivingChannelAdapter inbound(AbstractServerConnectionFactory cf) {
        TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
        adapter.setConnectionFactory(cf);
        adapter.setOutputChannel(tcpIn());
        return adapter;
    }

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

@Transformer(inputChannel = "tcpIn", outputChannel = "serviceChannel")
    @Bean
    public ObjectToStringTransformer transformer() {
        return new ObjectToStringTransformer();
    }

@ServiceActivator(inputChannel = "serviceChannel")
    public void service(String in) {
        System.out.println(in);
    }

}

Solution

This application is both a client and a server.

This question is specifically about how to write server-side (accept connections) using Spring Integration.

The main() method is just a test to connect to the server side. It uses the standard Java Sockets API; It can also be written to use Spring Integration components on the client side.

By the way, you don’t have to use XML to write Spring Integration applications, you can configure them using annotations, or use Java DSLs. Read the documentation.

Edit

Client/server example using Java DSL

@SpringBootApplication
public class So54057281Application {

public static void main(String[] args) {
        SpringApplication.run(So54057281Application.class, args);
    }

@Bean
    public IntegrationFlow server() {
        return IntegrationFlows.from(Tcp.inboundGateway(
                    Tcp.netServer(1234)
                        .serializer(codec()) // default is CRLF
                        .deserializer(codec()))) // default is CRLF
                .transform(Transformers.objectToString()) // byte[] -> String
                .<String, String>transform(p -> p.toUpperCase())
                .get();
    }

@Bean
    public IntegrationFlow client() {
        return IntegrationFlows.from(MyGateway.class)
                .handle(Tcp.outboundGateway(
                    Tcp.netClient("localhost", 1234)
                        .serializer(codec()) // default is CRLF
                        .deserializer(codec()))) // default is CRLF
                .transform(Transformers.objectToString()) // byte[] -> String
                .get();
    }

@Bean
    public AbstractByteArraySerializer codec() {
        return TcpCodecs.lf();
    }

@Bean
    @DependsOn("client")
    ApplicationRunner runner(MyGateway gateway) {
        return args -> {
            System.out.println(gateway.exchange("foo"));
            System.out.println(gateway.exchange("bar"));
        };
    }

public interface MyGateway {

String exchange(String out);

}

}

Result

FOO
BAR

Related Problems and Solutions