一、简介
ChannelPipeline和ChannelHandler也是netty中重要的组件,并且它们的关系是较为密切的,所以在这里一起介绍
二、ChannelPipeline
每一个新创建的Channel
都会绑定一个流水线ChannelPipeline
,ChannelPipeline是一个由多个ChannelHandler(实际上是ChannelHandlerContext,不过它只是在ChannelHandler外面再包了一层而已)组成的一个双向链表
,ChannelPipeline与Channel、ChannelHandler的关系如下:
文章图片
如上图,ChannelHandler可分为两大类,入站处理器ChannelInboundHandler以及出站处理器ChannelOutboundHandler
,后面会再详细介绍
【【Netty】五、ChannelPipeline以及ChannelHandler】ChannelPipeline的工作流程,如下:
- ChannelPipeline传播事件时,判断下一个ChannelHandler的类型是否与事件运行方向相匹配
- 如上面例子,如果是
入站事件,那么事件会先流经入站处理器2,再流经入站处理器4,会跳过出站处理器
。
- 反之,如果是
出站事件,会先流经出站处理器3,再流经出站处理器1
ChannelPipeline的
入站操作
,通知ChannelInboundHandler在ChannelPipeline中发生的事件,如下
fireChannelRegistered |
调用下一个ChannelInboundHandler的channelRegistered方法 |
fireChannelUnregistered |
调用下一个ChannelInboundHandler的fireChannelUnregistered方法 |
fireChannelActive |
调用下一个ChannelInboundHandler的fireChannelActive方法 |
fireChannelInactive |
调用下一个ChannelInboundHandler的fireChannelInactive方法 |
fireExceptionCaught |
调用下一个ChannelInboundHandler的fireExceptionCaught方法 |
fireUserEventTriggered |
调用下一个ChannelInboundHandler的fireUserEventTriggered方法 |
fireChannelRead |
调用下一个ChannelInboundHandler的fireChannelRead方法 |
fireChannelReadComplete |
调用下一个ChannelInboundHandler的fireChannelReadComplete方法 |
fireChannelWritabilityChanged |
调用下一个ChannelInboundHandler的fireChannelWritabilityChanged方法 |
ChannelPipeline的
出站操作
,如下
bind |
将Channel绑定到一个本地地址,将调用下一个ChannelOutboundHandler的bind方法 |
connect |
将Channel连接到一个远程地址,将调用下一个ChannelOutboundHandler的connect方法 |
disconnect |
将Channel断开连接,将调用下一个ChannelOutboundHandler的disconnect方法 |
close |
将Channel关闭,将调用下一个ChannelOutboundHandler的close方法 |
deregister |
将Channel从EventLoop中注销,将调用下一个ChannelOutboundHandler的deregister方法 |
flush |
冲刷Channel里的缓存数据,将调用下一个ChannelOutboundHandler的flush方法 |
write |
将消息写入Channel,将调用下一个ChannelOutboundHandler的write方法 |
writeAndFlush |
这是个write()和flush()方法的结合 |
read |
请求从Channel中读取更多数据,将调用下一个ChannelOutboundHandler的read方法 |
三、ChannelHandler
上面已经介绍ChannelHandler有两个重要的子接口,分别是
ChannelInboundHandler 和 ChannelOutboundHandler
- ChannelInboundHandler:
处理入站数据以及各种状态变化
- ChannelOutboundHandler:
处理出站数据并且允许拦截所有操作
ChannelInboundHandler的生命周期方法将
会在数据被接收时或者与其对应的Channel状态发生改变时被调用
,如下
channelRegistered |
当Channel已经注册到对应的EventLoop时被调用 |
channelUnregistered |
当Channel从它的EventLoop注销时被调用 |
channelActive |
当Channel处于活动状态时被调用 |
channelInactive |
当Channel离开活动状态时被调用 |
channelReadComplete |
当Channel的一个读操作完成时被调用 |
channelRead |
当Channel读取数据时被调用 |
channelWritabilityChanged |
当Channel的可写状态发生改变时被调用 |
userEventTriggered |
当ChannelInboundHandler.fireUserEventTriggered()方法被调用时调用 |
ChannelOutboundHanlder
处理出站操作和数据
,方法如下
bind |
当请求将Channel绑定到本地地址时被调用 |
connect |
当请求将Channel连接到远程节点时被调用 |
disconnect |
当请求将Channel从远程节点断开时被调用 |
close |
当请求关闭Channel时被调用 |
deregister |
当请求将Channel从它的EventLoop注销时被调用 |
read |
当请求从Channel读取更多的数据时被调用 |
flush |
当请求通过Channel将入队数据冲刷到远程节点时被调用 |
write |
当请求通过Channel将数据写到远程节点时被调用 |
四、总结
每个Channel都绑定了一个ChannelPipeline,而ChannelPipeline又是由一系列的ChannelHandler连接而成的。当一个入站事件进入时,该事件会从头到尾流经ChannelPipeline的入站处理器ChannelInboundHandler,而当一个出站事件触发时,该事件会从尾到头流经ChannelPipeline的出站处理器ChannelOutboundHandler。
推荐阅读