使用 Netty 进行服务端程序开发时, 主要涉及端口监听、EventLoop 线程池创建、NioServerSocketChannel 和 ChannelPipeline 初始化等
netty decode
extends LengthFieldBasedFrameDecoder 协议解码器
LengthFieldBasedFrameDecoder是netty解决拆包粘包问题的一个重要的类
public LengthFieldBasedFrameDecoder(
int maxFrameLength, //1024*1024*20 最大帧长度。也就是可以接收的数据的最大长度。如果超过,此次数据会被丢弃
int lengthFieldOffset, //0 长度域偏移。就是说数据开始的几个字节可能不是表示数据长度,需要后移几个字节才是长度域。
int lengthFieldLength, //4 长度域字节数。用几个字节来表示数据长度。
int lengthAdjustment, //0 数据长度修正。因为长度域指定的长度可以使header+body的整个长度,也可以只是body的长度。如果表示header+body的整个长度,那么我们需要修正数据长度。
int initialBytesToStrip // 4 跳过的字节数。如果你需要接收header+body的所有数据,此值就是0,如果你只想接收body数据,那么需要跳过header所占用的字节数。
)
extends MessageToByteEncoder < RemotingCommand > 协议编码器
RemotingCommand.encode();
closeChannel
几个常见的类
ServerBootstrap
netty服务器的帮助类
NioEventLoopGroup
处理I/O操作的多线程事件循环相当于一组线程池,服务器一般需要指定两个NioEventLoopGroup,一个作为监控tcp连接的,一个作为处理io事件的,前者默认1个线程就可以,后者最好是cpu核心数的2倍 客户端用一个就够了
NioServerSocketChannel
主要是server端接收建立SocketChannel用的
NioSocketChannel
主要是客户端接收SocketChannel用的
ChannelInboundHandlerAdapter
可以重写的各种事件处理程序方法,包括channelRead()、exceptionCaught()等方法
SimpleChannelInboundHandler
可以重写的各种事件处理程序方法,包括channelRead0()方法 这个可以跟指定的消息类型比上面的,如果自定义的消息类型用这个稍微多一点
ChannelPipeline
存放各种处理器,包括解码器,编码器等自定义处理器,idleStateHandler一定要放在第一个,传送数据时,编码器和解码器一定要放在前面,这个加载是分顺序的
ChannelHandlerContext
ChannelHandlerContext的writeAndFlush和ChannelHandlerContext.channel().writeAndFlush()是有区别的 前者是从当前hanler从后往前找OutputboundHandler,然后交给它执行的,后者是从最后一个开始执行handler的,最常见就是写错pipeline中的顺序后,客户端或服务器发消息就收不到了
ChannelInitializer
客户端和服务器都要用这个的SocketChannel,初始化的时候,加载ChannelPipeline
Bootstrap
客户端的连接帮助类
idleStateHandler
Netty 可以使用 IdleStateHandler 来实现连接管理,当连接空闲时间太长(没有发送、接收消息)时则会触发一个事件,我们便可在该事件中实现心跳机制
Netty 优雅退出的接口和总入口是 EventLoopGroup,调用它的shutdownGracefully 方法即可,除了无参的 shutdownGracefully方法,还可以指定退出的超时时间和周期