Netty源码-11-Pipeline
在Channel的初始化过程中会给每个Channel实例构造一个Pipeline,因此研究pipeline的入口就是构造方法。
一 类图
是继承关系上看,pipeline的实现比较简单。
二 JavaDoc
Netty采用Reactor的线程模型,一个IO线程负责读写,至于怎么操作读写的逻辑则定义在不同的handler中,pipline就是handler的栖身之所,pipeline负责组织和管理着。
将数据流转抽象定义为:
- 入站 从Socket流向Netty的Channel。
- 出站 从Netty的Channel流向Socket。
三 Demo
java
1 |
|
从demo的输出直观看出:
- 入站事件 pipeline从head发布事件->tail。
- 出站事件 pipeline从tail发布事件->head。
四 构造方法
java
1 |
|
内部就是一条双向链表,对于hanlder本身标识它对入站事件还是出站事件感兴趣,然后来了事件就顺着链表以职责链设计模式走一遍,哪个handler感兴趣就自己触发回调。
- 入站事件 从head->tail走一遍。
- 出站事件 从tail->head走一遍。
pipeline并没有将handler直接组织成双链表的节点,而是将handler封装成了HandlerContext。
而二者的区别在于:
- Handler - 执行逻辑处理。
- HandlerContext - 干预事件传播机制。
1 HeadContext
java
1 |
|
2 TailContext
java
1 |
|
3 AbstractChannelHandlerContext
怎么标识一个handler是属于入站还是出站就是通过这个executionMask来体现的。
java
1 |
|
通过位运算便可以组合出每个handler的感兴趣事件集合,来标榜每个handler是属于入站类型还是出站类型。
java
1 |
|
上面这些枚举也对应着每个API,也可以直接看JavaDoc的说明:
五 入站事件
比如ChannelRead属于入站事件。
java
1 |
|
java
1 |
|
java
1 |
|
java
1 |
|
1 HandlerContext处理事件
HandlerContext本身组合了handler,所以可以执行处理逻辑。
2 HandlerContext干预事件传播
java
1 |
|
HandlerContext处理完逻辑之后还可以决定是否将事件继续传播下去,还是到此为止。
然后就是周而复始:
- invokeChannelRead
- channelRead
- fireChannelRead
每个入站处理器的逻辑都定义在channelRead(…)被回调,在fireChannelRead向后传播。
从入站事件传播就可以推出来出站事件的逻辑:
- pipline发布的出站事件以tail为起始点,开始传播
- 每个处理器处理完回调逻辑,继续顺着tail->head的方向传播事件
六 出站事件
比如Read属于出站事件。
java
1 |
|
java
1 |
|
java
1 |
|
java
1 |
|
Netty源码-11-Pipeline
https://bannirui.github.io/2023/03/06/Netty源码-11-Pipeline/