Fork me on GitHub

Netty源码剖析五pipeline

Pipe主要负责Netty事件的传播,

pipeline的初始化

Pipeline在创建Channel的时候被创建

在前面我们创建Channel的时候,不管是服务端channel还是客户端channel,都会调用到AbstractChannel的一个构造函数,在拆解关键pipeline的时候通过newChannelPipeline方法去创建,我们进入newChannelPipeline里面

在创建pipeline的时候,是把this当作参数,进入DefaultChannelPipeline

首先把channel保存,默认情况下会创建两个节点,TailContext和HeadContext,然后通过一个nex和prev把节点创建成双向链表节点。

Pipeline节点数据结构:ChannelHandlerContext

pipeline的节点都是这的数据结构,它继承了AttributeMap,ChannelInboundInvoker,ChannelOutboundInvoker,

Pipeline中的两大哨兵:head和tail

我们可以进入TailContext

继承于AbstractChannelHandlerContext,实现了ChannelInboundHandler,我们进入它的构造函数,通过super创建好节点信息后,把当前节点设置为已经添加。

name ,pipeline,inbound还是outbound,默认inbound是true,outbound是false,

添加ChannelHandler

判断是否重复添加

进入addList方法

继续跟进addList方法

进入checkMultiplicity

这里会判断hadnler是否是ChannelHandlerAdapter的实例,检查是否重复添加

创建节点并添加至链表

首先先判断,进入filename;创建完成后,addLast0,进入addLast0

如果没有名字,就会给你创建一个名字,如果传进来一个名字,就会check,是否重复

添加至链表

回调添加完成事件

如果不再这个线程,就放入一个任务队列里,否则就直接执行,进入callHandlerAdded0

删除ChannelHandler

找到节点

链表的删除

回调删除Handler事件

事件和异常的传播

何为inBound事件以及ChannelInboundHandler

ChannelRead事件的传播
SimpleBoundHandler处理器
  1. Netty是如何判断ChannelHandler类型的?

    当你调用pipeline调用节点时Netty会使用instanceof关键词来判断当前节点是属于inbound还是outbound类型,用一个boolean变量来标识

  2. 对于ChannelHandler的添加应该遵循什么样的顺序?

    inbound事件的传播和添加ChannelHandler的事件正相关,而outbound和添加ChannelHandler事件传播和添加ChannelHandler逆相关。

  3. 用户手动触发事件传播,不同的触发方式有什么样的区别?

    通过Channel触发事件后,从我们head节点传播是inbound事件,从tail事件传播是outbound事件,如果是inbound事件就会从开始一直传到inbound,如果是outbound事件,就从开始一直传到第一个outbound事件。