SpringBoot quickly builds TCP server and client

Due to work needs, I studied the process of setting up TCP communication with SpringBoot. For those who need it in engineering, I just want to quickly build a usable service.

I have read many other tutorials, but I feel they are too complicated and easy to mess up. Here I will only talk about efficiency and show the quick construction process.

TCPServer

Since the TCP protocol is implemented by Netty, Netty dependencies are introduced.

<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>4.1.25.Final</version>
</dependency>

Configure TCPServer

@Component
@Slf4j
@Data
@ConfigurationProperties(prefix = "tcp.server")
public class TCPServer implements CommandLineRunner {
    private Integer port;

    @Override
    public void run(String... args) throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    ChannelPipeline pipeline = channel.pipeline();
                    pipeline.addLast(new StringEncoder());
                    pipeline.addLast(new StringDecoder());
                    pipeline.addLast(new TCPServerHandler());
                }
            })
            .option(ChannelOption.SO_BACKLOG, 128)
            .childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture future = bootstrap.bind(port).sync();
            log.info("TCP server started and listening on port " + port);

            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

application.yml configuration file

tcp:
 server:
  port: 8888 #Server port

ConfigurationTCPServerHandler

@Slf4j
@Component
public class TCPServerHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        log.info("Receive client message:/n"+ msg);
        Object parse = JSONUtils.parse(msg);
        System.out.println("parse = " + parse);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("TCPServerAbnormal", cause);
        ctx.close();
    }
}

TCPClient

The configuration of the client is similar

Netty dependency

<dependency>
  <groupId>io.netty</groupId>
  <artifactId>netty-all</artifactId>
  <version>4.1.25.Final</version>
</dependency>

Configure TCPClient

@Component
@Slf4j
@Data
@ConfigurationProperties(prefix = "tcp.client")
public class TCPClient implements CommandLineRunner {
    private String host ;
    private Integer port;
    @Override
    public void run(String... args) throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap()
                    .group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new TCPClientHandler());
                        }
                    });
            ChannelFuture future = bootstrap.connect(host, port).sync();
            log.info("TCPClient Start , Connect host:"+host+":"+port);
            future.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("TCPClient Error", e);
        } finally {
            group.shutdownGracefully();
        }
    }
}

application.yml configuration file

tcp:
 client:
  port: 8080 #Server port to connect to
  host: 127.0.0.1 #Connected server domain name

Configure TCPServerHandler

@Slf4j
@Component
public class TCPClientHandler extends SimpleChannelInboundHandler<String> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        log.info("Receive TCPServer Message:\n"+ msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("TCPClient Error", cause);
        ctx.close();
    }
}

This completes the entire construction process. The important things are the port of the server, the URL for the client to connect to the server, and the processing method of receiving messages. You can explore other details slowly by yourself.