ChannelPipeline简介
Netty 的ChannelPipeline和ChannelHandler 机制类似于Servlet和Filter过滤器,这类拦截实际上是职责链模式的一种变形,主要是为了方便事件的拦截和用户业务逻辑的定制。
ChannelPipeline类是ChannelHandler实例对象的链表,用于处理或截获通道的接收和发送数据。它提供了一种高级的截取过滤模式(类似serverlet中的filter功能),让用户可以在ChannelPipeline中完全控制一个事件以及如何处理ChannelHandler,ChannelPipeline的交互。
每个新的通道Channel,都会创建一个新的ChannelPipeline,并将器pipeline附加到channel中
ChannelPipeline将多个ChannelHandler链接在一起来让事件在其中传播处理。一个ChannelPipeline中可能不仅有入站处理器,还有出站处理器,入站处理器只会处理入站的事件,而出站处理器只会处理出站的数据,下面展示了一个同时具有入站处理器和出站处理器的ChannelPipeline:
ChannelPipeline功能说明
ChannelPipeline 是ChannelHandler 的容器,它负责ChannelHandler的管理和事件拦截与调度。
ChannelPipeline事件处理
(1) 底层的SocketChannel read() 方法读取ByeBuf,触发ChannelRead事件,由I/O线程NioEventLoop调用ChannelPipelint
的fireChannelRead(Object msg)方法,将消息(ByteBuf)传输到ChannelPipeline 中
(2)消息依次被HeadHandler,ChannelHandler1,ChannelHandler2... TailHandler拦截和处理,在这个过程中,任何ChannelHeadler 者可以中断当前的流程 ,结束消息的传递
(3)调用ChannelHeadlerContext的write方法发送消息,消息从TailHandler开始 ,途径ChannelHandler.....ChannelHandler1,
最终被添加到消息发送缓冲区中等待刷新和发送,在此过程中也可以中断消息传递。
ChannelPipeline的类继承图
ChannelPipeline 的inbound事件
当发生某个I/O事件的时候,例如链路关闭,读取操作完成等 ,都会产生一个事件,事件在pipeline 中得到传播和 处理,它是事件处理的总入口
方法 | 对应事件 |
---|---|
ChannelHandlerContext#fireChannelRegistered() | 注册连接 |
ChannelHandlerContext#fireChannelUnregistered() | 取消注册 |
ChannelHandlerContext#fireChannelActive() | 连接激活 |
ChannelHandlerContext#fireChannelRead(Object) | 读取数据 |
ChannelHandlerContext#fireChannelReadComplete() | 读取完成 |
ChannelHandlerContext#fireExceptionCaught(Throwable) | 发生异常 |
ChannelHandlerContext#fireUserEventTriggered(Object) | 用户事件触发 |
ChannelHandlerContext#fireChannelWritabilityChanged() | 可写状态改变 |
ChannelHandlerContext#fireChannelInactive() | 检测到连接断开 |
ChannelPipeline 的outbound事件
由用户线程或者代码 发起的I/O操作被称为outbound 事件
outbound事件
方法 对应事件 ChannelHandlerContext#bind(SocketAddress, ChannelPromise) 绑定端口 ChannelHandlerContext#connect(SocketAddress, SocketAddress, ChannelPromise) 发起连接 ChannelHandlerContext#write(Object, ChannelPromise) 写数据 ChannelHandlerContext#flush() 将写的数据发送 ChannelHandlerContext#read() 触发读操作 ChannelHandlerContext#disconnect(ChannelPromise) 与对方的连接断开 ChannelHandlerContext#close(ChannelPromise) 关闭自己的连接 ChannelHandlerContext#deregister() 触发取消注册
注意:的是不管是在inbound事件还是outbound事件处理的过程中发生异常,都会触发fireExceptionCaught方法的调用