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后面
上面添加Handler时会先将Handler构造成DefaultChannelHandlerContext,然后将新的handler添加到Head后面
2.addLast添加Handler是将Handler放在Tail的前面,同理路程如下
3.消息接收时是从Head开始向Tail流动直到某个handler没有将事件传递下去,或者tail结束(事件未传递是对应handler未调用ctx.fireChannelRead())
我们这里拆成如何获取数据流,我先说明是NioByteUnsafe中的read会获取数据流(为啥以后有时间会写一章分析)
上面这段代码是NioByteUnsafe的read方法,主要进行两件事获取数据传递事件。下面我们看下ctx.fireChannelRead源码
进一步进入到findContextInBound()源码中
进入invokeChannelRead方法深入源码中最终找到如下语句
4.消息发送一般是从Tail开启到head结束。当用户调用ctx.pipeline().writeAndFlush(xxx)输出流是从tail开启。如果我们在某个handler执行ctx.writeAndFlush(xx)那么事件是从当前Handler向Head流出。如果存在某个Handler为调用ctx.write()则事件会到处结束无法向head流动
DefaultChannelPipeline中writeAndFlush源码如下
进入findContextOutBound
总结:
netty中添加的handler是包装后的DefaultChannelHandlerContext其内部吃用next和pre成员变量将所有的handler从head 到tail连起来
netty的事件流动交给用户处理,如果向让事件向下进行比如解析数据量则在handler中调用fireChannelRead 如果想让发送数据事件流动则在handler中调用ctx.write