引言
公司的嵌入式同事想通过tcp协议传输数据给后台系统,事先写好的接口是http的,他们要改的话改动比较大,只能我这里改了。参考了好几个大佬的文章,为了方便程序员的朋友们,我在这做个总结,亲测可以运行,且不影响后台系统。
引入依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
业务处理
@Component
@Slf4j
@ChannelHandler.Sharable
public class NettyServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.getCause();
ctx.channel().close();
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
String message = byteBuf.toString(CharsetUtil.UTF_8);
System.out.print("Server received: " + message);
}
}
连接成功提示
@Component
public class NettyServerInitializer extends ChannelInitializer<SocketChannel> {
Logger log = LogManager.getLogger(NettyServerInitializer.class);
@Autowired
private NettyServerHandler nettyHandler;
//连接注册,创建成功,会被调用
@Override
protected void initChannel(SocketChannel ch) throws Exception {
log.info("==================netty报告==================");
log.info("信息:有一客户端链接到本服务端");
log.info("IP:{}", ch.remoteAddress().getAddress());
log.info("Port:{}", ch.remoteAddress().getPort());
log.info("通道id:{}", ch.id().toString());
log.info("==================netty报告完毕==================");
ChannelPipeline pipeline = ch.pipeline();
//定义读写空闲时间——(单位秒)
pipeline.addLast(new IdleStateHandler(180, 60,180));
//注册拦截器
pipeline.addLast(nettyHandler);
}
}
注册netty服务
@Component
@Slf4j
@Order(value = 2)
public class NettyServer implements ApplicationRunner {
@Autowired
private NettyServerInitializer nettyServerInitializer;
@Value("${netty.port}")
private int port;
public void serverRun() {
//循环组接收连接,不进行处理,转交给下面的线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
//循环组处理连接,获取参数,进行工作处理
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//服务端进行启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
//使用NIO模式,初始化器等等
serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(nettyServerInitializer);
//绑定端口
ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
log.info("tcp服务器已经启动…………");
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
@Async
@Override
public void run(ApplicationArguments args) throws Exception {
serverRun();
}
}
修改启动类
//在启动类上方加入
@EnableAsync
遇到和我一样netty启动了,但是后台系统没启动的友友们参考我这个方法就可以了。