1.Netty的业务场景
平台主要需求是和硬件(铁路小车安装的硬件)对接,并定时对设备进行监控检查,需要使用Netty作为通信中间件来监听端口,小车上的硬件通过TCP连接向服务端发送指令,后台主要是通过netty的ChannelHandler来实现对硬件数据的接收和处理。我的项目是把接收到的数据存入数据库,当然也可以放到缓存中。由于我也是刚开始接触netty,所以直接上代码,至于原理请自行百度。
2. Netty的主要组件
2.1 Channel
Channel作为Netty网络通信的主体,可以看作是通讯的载体,主要有三个状态:打开、关闭、连接。
Channel主要的IO操作:读(read)、写(write)、连接(connect)、绑定(bind),均为异步,也就是说在调用如上方法后,并不保证IO操作完成,但会在IO操作成功、失败或取消后,生成相应的记录保存在一个凭证中并返回。
3.下面把项目代码贴出来:
spring boot项目netty依赖
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.0.Final</version>
</dependency>
3.1 Netty服务 服务启动监听器
package com.htkj.netty.server;
import com.htkj.netty.handler.DecoderHandler;
import com.htkj.netty.handler.ServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
/**
* Netty服务 服务启动监听器
* @author zl
* @date 2019-12-11
*
*/
@Component
public class NettyServer {
private static Logger logger = LoggerFactory.getLogger(ServerHandler.class);
@Value("${netty.port}")
private int port;
public static ServerSocketChannel serverSocketChannel;
@Autowired
private ServerHandler serverHandler;
public void start() throws Exception {
// 连接处理group
EventLoopGroup boss = new NioEventLoopGroup();
// 事件处理group
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();//1.创建ServerBootStrap实例
// 绑定处理group
bootstrap.group(boss, worker)//2.设置并绑定Reactor线程池:EventLoopGroup,EventLoop就是处理所有注册到本线程的Selector上面的Channel
.channel(NioServerSocketChannel.class)//3.设置并绑定服务端的channel
// 保持连接数
.option(ChannelOption.SO_BACKLOG, 1024)
// 有数据立即发送
.option(ChannelOption.TCP_NODELAY, true)
// 保持连接
.childOption(ChannelOption.SO_KEEPALIVE, true)
// 处理新连接
.childHandler(new ChannelInitializer<SocketChannel>() {//设置了客户端连接socket属性。
@Override
protected void initChannel(SocketChannel sc) throws Exception {
// 增加任务处理
ChannelPipeline p = sc.pipeline();
p.addLast(new DecoderHandler(), // 自定义解码器