zoukankan      html  css  js  c++  java
  • Netty学习总结(4)——图解Netty之Pipeline、channel、Context之间的数据流向

    以下所绘制图形均基于Netty4.0.28版本。

    一、connect(outbound类型事件)

    当用户调用channel的connect时,会发起一个outbound类型的事件,该事件将在pipeline中传递(pipeline.connect),首先由tail handler处理,该handler只是将事件透传给下一个outbound类型的用户Handler(如果有),事件依次传递下去,直到传递到head handler,该handler会调用unsafe.connect向eventloop(nio的selector)注册一个读事件。

    图解Netty之Pipeline、channel、Context之间的数据流向。

    二、connect成功之后数据流图(inbound类型事件)

    当用户发起一个connect请求后,当连接可用时,eventloop(底层使用nio的selector)会引发一个ChannelActive事件,该事件最先有unsafe捕获,之后会调用pipeline.fireChannelActive将该事件在pipeline中传播,紧接着会根据inbound类型事件的传递方式在各个handler和context之间进行链式传递。其中,有一个比较关注的地方是,在channelActive事件触发的时候,如果channel被设置成autoRead,那么此时还会调用channel.read方法,该方法并不是真正的从channel读取数据,而是向eventloop注册读事件(因为一个channel在向eventloop中注册时,默认不注册任何事件),关于channel.read的过程可以看下文的另一张图。

    图解Netty之Pipeline、channel、Context之间的数据流向。

    三、channel.read事件流图(outbound类型事件)

    当用户调用channel.read后,会发起一个outbound类型的事件,该事件最先会由pipeline中tail handler处理,该handler只是将该事件透传给前面一个outbound类型的用户handler(如果有的话),这样依次继续向前传递,直到传递到head handler,该handler会调用unsafe.read向eventloop注册读事件(也就是向nio的selector上添加读事件)

    图解Netty之Pipeline、channel、Context之间的数据流向。

    四、channel.write(outbound类型事件)

    与channel.read类型,wirte也是一个outbound类型事件,该事件最先会由pipeline中的tail handler透传给前面的一个outbound类型的用户handler(如果有的话),这样依次传递,直到传递给head handler,该handler会调用unsafe.write方法,这里的wirte并不会执行真正的发送,而是将要发送的数据缓存起来,直到调用flush时,这些数据才会执行真正的网络io。

    图解Netty之Pipeline、channel、Context之间的数据流向。

    五、flush(outbound类型事件)

    如前文所示,flush也是一个outbound类型的事件,与wirte不同,flush会执行真正的网络io操作。

    图解Netty之Pipeline、channel、Context之间的数据流向。

    六、当channel有数据可读时(inbound类型事件)

    当eventloop层检测到网络层有数据可读时(nio的selector返回相应的seleciontKeys),该事件会首先传递给unsafe,紧接着会调用pipeline.fireChannelRead,将事件开始在pipeline中传递,该事件最先会有head handler处理(head.fireChannelRead()),该handler直接将事件透传给下一个inbound类型的用户handler(如果有的话),该事件依次向下传递,直到传递到tail handler。

    图解Netty之Pipeline、channel、Context之间的数据流向。


  • 相关阅读:
    10分钟教你用Python玩转微信之抓取好友个性签名制作词云
    1. 配置win7下odbc数据源找不到数据库驱动的问题
    1. 加签和会签的区别
    4. mysql 1449 : The user specified as a definer ('test'@'%') does not exist 解决方法
    1. 在config.ini文件中加入dm.park.time=1,会使uap中的tomcat启动加快
    37. sqlplus工具连接服务端或其他电脑的oracle方式
    36. Oracle查询数据库中所有表的记录数
    4. mysql 查看数据库中所有表的记录数
    35. Oracle监听器启动出错:本地计算机上的OracleOraDb11g_home1TNSListener服务启动后又停止了解决方案
    4. powerdesigner 生成sql脚本步骤
  • 原文地址:https://www.cnblogs.com/zhanghaiyang/p/7212736.html
Copyright © 2011-2022 走看看