1 pipeline是什么?

ChannelPipeline是Netty中非常核心的概念。每个Netty SocketChannel包含一个ChannelPipeline。

ChannelPipeline包含ChannelHandler实例的list。当数据移入和移出SocketChannel时,将调用这些ChannelHandler实例。

ChannelHandler接口具有两个子接口:

  • ChannelInboundHandler
  • ChannelOutboundHandler

可以将ChannelInboundHandler和ChannelOutboundHandler实例都添加到Netty ChannelPipeline。

  • 添加了ChannelInboundHandler、ChannelOutboundHandler实例的ChannelPipeline
    Netty源码解析实战(6)-pipeline_Netty

从SocketChannel接收到数据后,该数据将传递到ChannelPipeline中的第一个ChannelInboundHandler。此ChannelInboundHandler处理数据,然后将数据传递到ChannelPipeline中的下一个ChannelInboundHandler。

实际上,ChannelInboundHandler可以在将接收到的数据传递到管道中的下一个处理器之前对其进行转换。例如,原始的字节可以转换为HTTP对象或其他一些对象。然后,管道中的下一个处理器将看到HTTP对象,而非原始数据。

当将数据写回到SocketChannel时,它以相同方式发生。数据从ChannelOutboundHandler传递到ChannelPipeline中的ChannelOutboundHandler,直到到达SocketChannel。 ChannelOutboundHandler实例还可以转换流程中的数据。

尽管该图将ChannelInboundHandler和ChannelOutboundHandler实例显示为单独的列表,但它们实际上位于同一list(管道)中。

  • 因此,若ChannelInboundHandler决定将某些内容写回SocketChannel,则数据将通过比ChannelInboundHandler写入数据更早的ChannelPipeline中位于所有ChannelOutboundHandler实例。
    Netty源码解析实战(6)-pipeline_Netty_02
    Netty具有编解码器(编码器+解码器)的概念。 Netty编解码器将字节转换为消息对象(Java对象),或将消息对象转换为字节。例如,编解码器可能会将传入的HTTP请求的原始字节转换为HTTP对象,或者将HTTP响应对象转换回原始字节。

Netty编解码器对象实际上只是一个(或两个)ChannelHandler实现。编解码器通常由将请求字节转换为对象的ChannelInboundHandler实现和将响应对象转换为字节的ChannelOutboundHandler组成。

Netty随附了几种不同协议的编解码器,例如HTTP,WebSocket,SSL / TLS等。为了将这些协议与Netty一起使用,您必须将相应的协议编解码器ChannelInboundHandler和ChannelOutboundHandler添加到要使用的SocketChannel的ChannelPipeline中协议。

  • netty是如何判断ChannelHandler类型的?
  • 对于ChannelHandler的添加应该遵循什么顺序?
  • 用户手动触发事件传播,不同的触发方式有什么区别?
2 pipeline初始化

pipeline在创建Channel的时候被创建
Netty源码解析实战(6)-pipeline_Netty_03
Netty源码解析实战(6)-pipeline_Netty_04
Netty源码解析实战(6)-pipeline_Netty_05

Pipeline节点数据结构: ChannelHandlerContext
Netty源码解析实战(6)-pipeline_Netty_06
Netty源码解析实战(6)-pipeline_Netty_07
看看其一个实现类
Netty源码解析实战(6)-pipeline_Netty_08
基本数据结构组件
Netty源码解析实战(6)-pipeline_Netty_09

Pipeline中的两大哨兵: head和tail
Netty源码解析实战(6)-pipeline_Netty_10
Netty源码解析实战(6)-pipeline_Netty_11
Netty源码解析实战(6)-pipeline_Netty_12
Netty源码解析实战(6)-pipeline_Netty_13
Netty源码解析实战(6)-pipeline_Netty_14

3 添加ChannelHandler

先看看用户代码
Netty源码解析实战(6)-pipeline_Netty_15

判断是否重复添加
Netty源码解析实战(6)-pipeline_Netty_16
Netty源码解析实战(6)-pipeline_Netty_17
Netty源码解析实战(6)-pipeline_Netty_18
Netty源码解析实战(6)-pipeline_Netty_19
Netty源码解析实战(6)-pipeline_Netty_20
Netty源码解析实战(6)-pipeline_Netty_21
Netty源码解析实战(6)-pipeline_Netty_22
Netty源码解析实战(6)-pipeline_Netty_23
Netty源码解析实战(6)-pipeline_Netty_24
Netty源码解析实战(6)-pipeline_Netty_25
Netty源码解析实战(6)-pipeline_Netty_26
Netty源码解析实战(6)-pipeline_Netty_27
Netty源码解析实战(6)-pipeline_Netty_28
Netty源码解析实战(6)-pipeline_Netty_29
Netty源码解析实战(6)-pipeline_Netty_30
Netty源码解析实战(6)-pipeline_Netty_31
Netty源码解析实战(6)-pipeline_Netty_32
Netty源码解析实战(6)-pipeline_Netty_33
Netty源码解析实战(6)-pipeline_Netty_34
Netty源码解析实战(6)-pipeline_Netty_35

6 outBound事件的传播

Netty源码解析实战(6)-pipeline_Netty_36
Netty源码解析实战(6)-pipeline_Netty_37
Netty源码解析实战(6)-pipeline_Netty_38
Netty源码解析实战(6)-pipeline_Netty_39
Netty源码解析实战(6)-pipeline_Netty_40
Netty源码解析实战(6)-pipeline_Netty_41
Netty源码解析实战(6)-pipeline_Netty_42
Netty源码解析实战(6)-pipeline_Netty_43
Netty源码解析实战(6)-pipeline_Netty_44
Netty源码解析实战(6)-pipeline_Netty_45
Netty源码解析实战(6)-pipeline_Netty_46
Netty源码解析实战(6)-pipeline_Netty_47
Netty源码解析实战(6)-pipeline_Netty_48
Netty源码解析实战(6)-pipeline_Netty_49
Netty源码解析实战(6)-pipeline_Netty_50
Netty源码解析实战(6)-pipeline_Netty_51
Netty源码解析实战(6)-pipeline_Netty_52
Netty源码解析实战(6)-pipeline_Netty_53
同理以后的过程
Netty源码解析实战(6)-pipeline_Netty_54

7 异常的传播

Netty源码解析实战(6)-pipeline_Netty_55
Netty源码解析实战(6)-pipeline_Netty_56
Netty源码解析实战(6)-pipeline_Netty_57
Netty源码解析实战(6)-pipeline_Netty_58
Netty源码解析实战(6)-pipeline_Netty_59
Netty源码解析实战(6)-pipeline_Netty_60
Netty源码解析实战(6)-pipeline_Netty_61
Netty源码解析实战(6)-pipeline_Netty_62
Netty源码解析实战(6)-pipeline_Netty_63
Netty源码解析实战(6)-pipeline_Netty_64
最佳实践
Netty源码解析实战(6)-pipeline_Netty_65
Netty源码解析实战(6)-pipeline_Netty_66

8 pipeline总结

Netty源码解析实战(6)-pipeline_Netty_67
Netty源码解析实战(6)-pipeline_Netty_68
调用 pipeline 添加节点时,netty 会使用 instanceof 关键字判断当前节点是 inboound 还是 outbound 类型,分别用不同的 boolean 类型变量标识
Netty源码解析实战(6)-pipeline_Netty_69
inbound 事件类型顺序正相关
outbound 逆相关
Netty源码解析实战(6)-pipeline_Netty_70
异常处理器要么从 head 或者 tail 节点开始传播
inbound事件则从当前节点开始传递到最后节点
outbound事件则从当前节点开始传递 到第一个 outbound节点