Netty源码死磕(ChannelPipeline的执行过程)

2020-04-14  本文已影响0人  香芋牛奶面包

引言

上文有提到如果Selector轮询到网络IO事件了,则会调用该Channel对应的ChannelPipeline来依次执行对应的ChannelHandler

ChannelPipelineChannelHandler的关系

那么这里的ChannelPipelineChannelHandler之间到底是什么关系呢?
其实我们可以理解为类似于一个过滤器模式,其中ChannelPipeline是一个存放各种过滤器的管道容器,而ChannelHandler则对应着单个过滤器实体

执行流程

我们来看下ChannelPipline的工作流程

  1. NioEventLoop 触发读事件,会调用SocketChannel所关联的ChannelPipline
  2. 由上一步读取到的消息会在ChannelPipline中依次被多个ChannelHandler处理
  3. 处理完消息会调用ChannelHandlerContextwrite方法发送消息,发送的消息同样也会经过ChannelPipline中的多个ChannelHandler处理

上面的流程其实主要分成了两步,触发读事件和写事件。对应这两种事件,NettyChannelHandler也分为了两大类

  1. ChannelInboundHandler 顾明思义,负责处理链路读事件的Handler。通常由IO线程触发
  2. ChannelOutboundHandler,负责链路写事件的Handler
    也就是说当IO线程触发读事件时,只会调用ChannelInboundHandler的实现handler

下面我们看下ChannelHandlerChannelPipline中是一个什么样的结构

image.png

可以看到ChannelHandler在加入ChannelPipline之前会被封装成一个ChannelHandlerContext节点类加入到一个双向链表结构中。除了头尾两个特殊的ChannelHandlerContext实现类,我们自定义加入的ChannelHandler最终都会被封装成一个DefaultChannelHandlerContext类。

image.png

当有读事件被触发时,ChannelHandler(会筛选类型为ChannelInboundHandler的Handler) 的触发顺序是 HeaderContext -> TailContext
当有写事件被触发时,ChannelHandler(会筛选类型为ChannelOutboundHandler的Handler) 的触发顺序与读事件相反是 TailContext -> HeaderContext

总结

本文比较简短,主要是为了理清ChannelPipelineChannelHandler的关系,以及ChannelHandlerChannelPipeline中的执行过程是怎样的

上一篇下一篇

猜你喜欢

热点阅读