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.