pipeline 事件传播的过程

简介

pipeline 和 ChannelHandlerContext, ChannelHandler三者之间的关系

pipeline 通过维持一个链表结构,链表节点是 ChannelHandlerContext,该节点持有 ChannelHandler。部分对 ChannelHandler 的操作直接暴露给 ChannelHandlerContext,因此我们可以直接操作 ChannelHandlerContext来间接操作 ChannelHandler

channelRead 事件为例,描述 inBoundoutBound 的传播过程。总体如下图:
yeeB6g.png

inBound事件

当发生某个IO事件的时候,例如链路建立链路关闭读取操作完成(register,read,active) 等,都会产生一个事件,事件在pipeline中传播和处理

pipeline中以fireXXX命名的方法都是从IO线程向用户业务Handler的inBound事件,它们的实现因功能而异,但是处理步骤类似。如下:

  • 调用HeadHandler对应的fireXXX方法;
  • 执行事件相关的逻辑操作。

当调用ChannelHandlerContext.fireXXX方法 (例如: fireChannelRead()) 的时候,事件会从当前节点向下进行传播,就是找到下一个ChannelInBoundHandler,然后调用ChannelInBoundHandler的channelXXX方法。

如果不覆盖channelXXX方法的话,默认会将这个消息在pipeline上从头到尾进行传播,最后会调用到Tail节点的channelXXX方法,如果说有消息一直调用到Tail节点的channelXXX方法,说明前面的channelHandler没有处理消息,使得消息一直到了尾节点,尾节点需要进行一定的释放,防止内存泄漏。

SimpleChannelInBoundHandler#channelRead0方法会帮助自动释放ByteBuf,它的channelRead方法调用channelRead0()并且释放ByteBuf。

outBound事件

由用户线程或者代码发起的IO操作被称做outBound事件。

ChannelOutBoundHandler的添加顺序和事件传播的顺序是相反的。而outBound事件是寻找下一个ChannelOutBoundHandler,调用该handler的方法,最终会从Tail节点传播到Head节点。

总结:每次使用pipeline传播调用方法时,是从头结点或者尾节点开始传播,而使用ChannelHandlerContext则是从当前节点开始传播。

异常传播

异常的传播并不区分是inBoundHandler还是outBoundHandler,异常都会在上面进行传播。

异常的传播顺序: 是和handler添加的顺序相关(一样)。默认情况下异常的传播是直接拿到当前节点的下一个节点,最终会传播到Tail节点exceptionCaught(),Tail节点最终会打印这个exception,通知这个异常并没有被处理。如果说我们需要对异常做一个处理的话,最好在pipeline最后添加一个异常处理器,最终可以对异常进行一个统一的处理。

inBound事件的传播

handler之间的传播信息通过 fireXXX方法:其区别是从哪个节点开始传播。

ctx.pipeline().fireChannelRead(msg); 从头节点HeadContext开始传播
ctx.fireChannelRead(msg); 从当前节点往下传播事件

@Override
public void channelRead(ChannelHandlerContext ctx,  Object msg)throws Exception {
   

    //调用通道的fireChannelRead方法是从头节点HeadContext开始传播
    ctx.pipeline(). fireChannelRead(msg);
    
    //调用数据节点的传播方法是从当前节点往下传播事件
    ctx.fireChannelRead (msg)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值