Netty学习总结(4)——图解Netty之Pipeline、channel、Context之间的数据流向
2016-11-21 10:01
274 查看
以下所绘制图形均基于Netty4.0.28版本。
一、connect(outbound类型事件)
当用户调用channel的connect时,会发起一个outbound类型的事件,该事件将在pipeline中传递(pipeline.connect),首先由tail handler处理,该handler只是将事件透传给下一个outbound类型的用户Handler(如果有),事件依次传递下去,直到传递到head
handler,该handler会调用unsafe.connect向eventloop(nio的selector)注册一个读事件。
二、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的过程可以看下文的另一张图。
三、channel.read事件流图(outbound类型事件)
当用户调用channel.read后,会发起一个outbound类型的事件,该事件最先会由pipeline中tail handler处理,该handler只是将该事件透传给前面一个outbound类型的用户handler(如果有的话),这样依次继续向前传递,直到传递到head
handler,该handler会调用unsafe.read向eventloop注册读事件(也就是向nio的selector上添加读事件)
四、channel.write(outbound类型事件)
与channel.read类型,wirte也是一个outbound类型事件,该事件最先会由pipeline中的tail handler透传给前面的一个outbound类型的用户handler(如果有的话),这样依次传递,直到传递给head handler,该handler会调用unsafe.write方法,这里的wirte并不会执行真正的发送,而是将要发送的数据缓存起来,直到调用flush时,这些数据才会执行真正的网络io。
五、flush(outbound类型事件)
如前文所示,flush也是一个outbound类型的事件,与wirte不同,flush会执行真正的网络io操作。
六、当channel有数据可读时(inbound类型事件)
当eventloop层检测到网络层有数据可读时(nio的selector返回相应的seleciontKeys),该事件会首先传递给unsafe,紧接着会调用pipeline.fireChannelRead,将事件开始在pipeline中传递,该事件最先会有head handler处理(head.fireChannelRead()),该handler直接将事件透传给下一个inbound类型的用户handler(如果有的话),该事件依次向下传递,直到传递到tail
handler。
一、connect(outbound类型事件)
当用户调用channel的connect时,会发起一个outbound类型的事件,该事件将在pipeline中传递(pipeline.connect),首先由tail handler处理,该handler只是将事件透传给下一个outbound类型的用户Handler(如果有),事件依次传递下去,直到传递到head
handler,该handler会调用unsafe.connect向eventloop(nio的selector)注册一个读事件。
二、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的过程可以看下文的另一张图。
三、channel.read事件流图(outbound类型事件)
当用户调用channel.read后,会发起一个outbound类型的事件,该事件最先会由pipeline中tail handler处理,该handler只是将该事件透传给前面一个outbound类型的用户handler(如果有的话),这样依次继续向前传递,直到传递到head
handler,该handler会调用unsafe.read向eventloop注册读事件(也就是向nio的selector上添加读事件)
四、channel.write(outbound类型事件)
与channel.read类型,wirte也是一个outbound类型事件,该事件最先会由pipeline中的tail handler透传给前面的一个outbound类型的用户handler(如果有的话),这样依次传递,直到传递给head handler,该handler会调用unsafe.write方法,这里的wirte并不会执行真正的发送,而是将要发送的数据缓存起来,直到调用flush时,这些数据才会执行真正的网络io。
五、flush(outbound类型事件)
如前文所示,flush也是一个outbound类型的事件,与wirte不同,flush会执行真正的网络io操作。
六、当channel有数据可读时(inbound类型事件)
当eventloop层检测到网络层有数据可读时(nio的selector返回相应的seleciontKeys),该事件会首先传递给unsafe,紧接着会调用pipeline.fireChannelRead,将事件开始在pipeline中传递,该事件最先会有head handler处理(head.fireChannelRead()),该handler直接将事件透传给下一个inbound类型的用户handler(如果有的话),该事件依次向下传递,直到传递到tail
handler。
相关文章推荐
- Netty学习总结(4)——图解Netty之Pipeline、channel、Context之间的数据流向
- 图解Netty之Pipeline、channel、Context之间的数据流向。
- Netty Pipeline、channel、Context之间的数据流向
- Netty中Channel、ChannelPipeline、ChannelHandler、ChannelHandlerContext之间的关系
- Netty源码之ChannelPipeline和ChannelHandlerContext
- netty源码分析之-Channel、ChannelPipeline、ChannelHandler以及 ChannelHandlerContext 详解(2)
- Netty源码分析(三)—数据管道ChannelPipeline源码分析
- Netty源码分析:图解Pipeline、Handler、Context
- netty源码分析(十二)Channel与ChannelHandler及ChannelHandlerContext之间的关系分析
- netty源码分析之ChannelPipeline
- 二. 学习Netty之ChannelHandlerContext
- EF数据存贮问题二之“无法定义这两个对象之间的关系,因为它们附加到不同的 ObjectContext 对象”
- 网络-Netty(一)-NIO概念Channel是一个对象,可以通过它读取和写入数据。可以把它看做IO中的流。但是它和流相比还有一些不同:
- 03 netty channelPipeline
- 【转】Netty那点事(三)Channel中的Pipeline
- Netty那点事: 概述, Netty中的buffer, Channel与Pipeline
- Netty 4.0 源码分析(三):Channel和ChannelPipeline
- Netty那点事(三)Channel中的Pipeline
- Netty ChannelPipeline动态修改ChannelHandler
- Netty源码解读(三)Channel与Pipeline