netty中添加处理器讲解

netty中我们会添加一些处理器,如果对其添加流程及内部结构不清楚经常会出现各种问题,我先给出一幅处理器整体排版图

netty中添加处理器讲解

addFist添加Handler是将Handler放在Head后面

addLast添加Handler是将Handler放在Tail的前面

消息接收时是从Head开始向Tail流动直到某个handler没有将事件传递下去,或者tail结束(事件未传递是对应handler未调用ctx.fireChannelRead())

消息发送一般是从Tail开启到head结束。当用户调用ctx.pipeline().writeAndFlush(xxx)输出流是从tail开启。如果我们在某个handler执行ctx.writeAndFlush(xx)那么事件是从当前Handler向Head流出。如果存在某个Handler未调用ctx.write()则事件会到此结束无法向head流动

 

源码分析解读:

1.addFirst添加Handler是将Handler存放在Head后面

netty中添加处理器讲解

netty中添加处理器讲解

上面添加Handler时会先将Handler构造成DefaultChannelHandlerContext,然后将新的handler添加到Head后面

 

2.addLast添加Handler是将Handler放在Tail的前面,同理路程如下

netty中添加处理器讲解

 

3.消息接收时是从Head开始向Tail流动直到某个handler没有将事件传递下去,或者tail结束(事件未传递是对应handler未调用ctx.fireChannelRead())

我们这里拆成如何获取数据流,我先说明是NioByteUnsafe中的read会获取数据流(为啥以后有时间会写一章分析)

netty中添加处理器讲解

上面这段代码是NioByteUnsafe的read方法,主要进行两件事获取数据传递事件。下面我们看下ctx.fireChannelRead源码

netty中添加处理器讲解

进一步进入到findContextInBound()源码中

netty中添加处理器讲解

进入invokeChannelRead方法深入源码中最终找到如下语句

netty中添加处理器讲解

 

4.消息发送一般是从Tail开启到head结束。当用户调用ctx.pipeline().writeAndFlush(xxx)输出流是从tail开启。如果我们在某个handler执行ctx.writeAndFlush(xx)那么事件是从当前Handler向Head流出。如果存在某个Handler为调用ctx.write()则事件会到处结束无法向head流动

DefaultChannelPipeline中writeAndFlush源码如下

netty中添加处理器讲解

netty中添加处理器讲解

进入findContextOutBound

netty中添加处理器讲解

 

总结:

netty中添加的handler是包装后的DefaultChannelHandlerContext其内部吃用next和pre成员变量将所有的handler从head 到tail连起来

netty的事件流动交给用户处理,如果向让事件向下进行比如解析数据量则在handler中调用fireChannelRead 如果想让发送数据事件流动则在handler中调用ctx.write