美文网首页netty
Netty4中Handler的执行顺序以及ctx.close()

Netty4中Handler的执行顺序以及ctx.close()

作者: virtual灬zzZ | 来源:发表于2022-11-02 13:12 被阅读0次

    1. ctx.close()会触发当前Handler和当前Handler之前的close事件;

    2. channel.close()所有Handler都会触发;

    这样的顺序对于write操作和close都是一样道理的。

    举例:netty服务端是这个添加顺序

    ch.pipeline().addLast(new InboundHandler1());  
    ch.pipeline().addLast(new InboundHandler2()); 
    ch.pipeline().addLast(new OutboundHandler1());  
    ch.pipeline().addLast(new OutboundHandler2()); 
    
    链表中的顺序为head->in1->in2->out1->out2->tail
    
    1、如果在InboundHandler2中执行的是ctx.channel().writeAndFlush,执行顺序是:
    InboundHandler1 
    InboundHandler2 
    OutboundHandler2
    OutboundHandler1
    

    结果证明:执行完InboundHandler1、InboundHandler2之后,由于InboundHandler2中执行的是ctx.channel().writeAndFlush,它会直接从tail开始往前找Outbound执行,链表中的顺序为head->in1->in2->out1->out2->tail,所以会执行out2,再执行out1

    2、如果在InboundHandler2中执行的是ctx.writeAndFlush,执行顺序是:
    InboundHandler1 
    InboundHandler2 
    

    结果证明,由于OutboundHandler1与OutboundHandler2的add在InboundHandler2之后,而InboundHandler2中执行的是ctx.writeAndFlush,它会从当前InboundHandler2的位置,往前找Outbound执行,根据链表中的顺序为head->in1->in2->out1->out2->tail,in2之前已经无Outbound,所以不会再有Outbound会执行

    上面两个已经能说明问题,为了方便对netty的handler执行不是太熟悉的读者理解,再举个例子:
    ch.pipeline().addLast(new OutboundHandler1());  
    ch.pipeline().addLast(new OutboundHandler2());  
    ch.pipeline().addLast(new InboundHandler1());  
    ch.pipeline().addLast(new InboundHandler2()); 
    链表中的顺序为head->out1->out2->in1->in2->tail
    
    1、如果在InboundHandler2中执行的是ctx.channel().writeAndFlush,执行顺序是:
    InboundHandler1 
    InboundHandler2 
    OutboundHandler2
    OutboundHandler1 
    

    结果证明,执行完InboundHandler2后,由于InboundHandler2中执行的是ctx.channel().writeAndFlush,它会从tail往前找Outbound执行,而链表中的顺序为head->out1->out2->in1->in2->tail,所以会继续执行到out2、out1

    2、如果在InboundHandler2中执行的是ctx.writeAndFlush,执行顺序是:
    InboundHandler1
    InboundHandler2
    OutboundHandler2 
    OutboundHandler1
    

    结果证明,执行完InboundHandler2后,由于InboundHandler2中执行的是ctx.writeAndFlush,它会从InboundHandler2位置往前找Outbound执行,而链表中的顺序为head->out1->out2->in1->in2->tail,所以会继续执行到out2、out1

    核心最容易让人误解的点总结:

    1、ctx.writeAndFlush只会从当前的handler位置开始,往前找outbound执行

    2、ctx.pipeline().writeAndFlush与ctx.channel().writeAndFlush会从tail的位置开始,往前找outbound执行

    相信你看到这里,基本能掌握channelHandlerContext调用与pipeline、channel调用的区别,但我敢肯定你只能记住3~5天就又忘记了;所以我再加一句记忆方法:

    每次add一个channelHandler都会创建一个channelHandlerContext与之绑定,channelHandlerContext的作用就是管理它所关联的channelHandler和在同一个pipeline中的其他channelHandler之间的交互,他是什么?他与某个channelHandler绑定,权利有限,只能从当前他所绑定的channelHandler开始搞事情;
    而pipeline与channel比较屌,可以指挥从头或者尾开始搞。

    注:channelRead以及channelActive等这些都会接着pipeline传递

    参考:
    一文搞懂Netty中Handler的执行顺序
    ctx.close() 和 ctx.channel().close() 到底有何区别?

    相关文章

      网友评论

        本文标题:Netty4中Handler的执行顺序以及ctx.close()

        本文链接:https://www.haomeiwen.com/subject/nldjtdtx.html