本文基于Netty 4
从网络上接收到的数据后,Netty 设计了一套Channel机制来传递和处理这些数据,这个机制包括Channel,ChannelHandler,ChannelHandlerContext和ChannelPipeline。
Channel
Channel与JDK中的Channel作用相当,是对I/O操作的封装,比如read(),write(),connect(),close()和bind()等,是Netty中非常核心的对象。我们经常使用的NioServerSocketChannel,NioSocketChannel就是其具体实现。Channel的状态改变都会触发相应事件传递到Pipeline中,被ChannelHandler处理,下图为Channel经常触发的事件
事件 | 说明 |
---|---|
ChannelRegistered | 这里的注册强调的是Channel与EventLoop是否关联,满足下列条件才能称为registered: 1. 将相关socket注册到selector上;2. Channel与EventLoop关联起来 |
ChannelActive | 满足下列两个条件,就是active了:1. channel 完成了注册;2. channel 绑定到了本地端口(对NioServerSocketChannel而言)或连接到了远程主机(对NioSocketChannel而言) |
ChannelHandler
ChannelHandler 是处理数据的核心对象,其对源端Channel触发的一系列事件进行处理。Netty提供了两个非常重要的子接口:
- ChannelInboundHandler
- ChannelOutboundHandler
对于Inbound和Outbound的理解:
Inbound: 数据或事件由外向内流,比如Channel注册成功触发的注册事件;Channel读好数据后的ChannelRead事件等;或者说是与网络交互完成,接下来要由Netty处理;
Outbound: 数据或事件由内向外流,比如Netty处理好数据后要write到网络;去网络方向read数据(read这一事件从内向外,read好数据后就是由外向内);或者说需要与网络进行交互的操作都称为Outbound;
ChannelInboundHandler
ChannelInboundHandler方法如下图所示,从方法名可看出,其是对Channel触发事件的处理;
Inbound 方法ChannelOutboundHandler
ChannelOutboundHandler的方法如下图所示,都是与底层网络交互的;其实这些方法最后都会转调到Channel中定义的I/O方法上去,因为只有Channel才是与网络进行交互的
Oubound 方法ChannelHandlerContext
ChannelHandlerContext是ChannelHandler相互之间,ChannelHandler与ChannelPipeline之间交互的桥梁。当创建一个Channel时,也会创建相应的ChannelHandlerContext。ChannelHandlerContext另一个重要的作用是在Pipeline中传播事件
ChannelPipeline
ChannelPipeline是一系列ChannelHandler的组合,与Channel相关的所有数据和事件都会流经相应的ChannelPipeline进行处理。ChannelPipeline也可以触发事件传播,与ChannelHandlerContext触发不同的是,ChannelPipeline触发的事件都是从第一个ChannelHandler开始处理,而ChannelHandlerContext触发的事件总是从下一个ChannelHandlerContext开始处理
Pipeline的事件流当事件流在ChannelPipeline中流动时,可以调用ChannelHandlerContext或ChannelPipeline的Outbound方法改变事件的流向
在程序中,要手动触发Inbound到Outbound方向的转变;举个例子,比如我们定义了若干个InboundHandler,处理了用户数据后,返回给用户一个Success,那么必须在某个InboundHandler里调用ChannelHandlerContext.write()方法让数据流改变方向,否则,永远都无法给用户返回;若不手动改变方向,输入数据最终会走到TailContext(默认最后一个InboundHandler)中,而这个Handler几乎什么都没做,那么OutBound方法永远都等不到被调用
事件流
无论是NioSocketChannel还是NioServerSocketChannel,Channel的事件都是按照下图所示流转
事件流
网友评论