本文主要包括:
(1)ChannelPipeline的功能说明和源码分析;
(2)ChannelHandler的功能说明和源码分析;
在netty中的ChannelPipeline和ChannelHandler的机制就很类似于J2EE中的Servlet和Filter过滤器,这类拦截器就很类似于责任链模式的一种变形。核心就是事件的拦截和用户业务逻辑的定制。
netty中channel过滤器实现原理和servlet的Filter基本一致,netty将Channel的数据管道抽象为ChannelPipeline,消息在ChannelPipeline中流动和传递。ChannelPipeline又持有IO事件拦截器ChannelHandler的链表,由ChannelPipeline中的channelHandler对IO事件进行拦截和处理,可以通过在ChannelPipeline中新增和删除ChannelHandler来实现不同业务逻辑的定制。这样就不需要更改ChannelHandler中的代码,就能实现扩展和修改。
1. ChannelPipeline功能说明
ChannelPipeline其实就是ChannelHandler的容器,它维护了一个ChannelHandler的链表。
(1)ChannelPipeline的消息事件处理过程
下图展示了一个消息被ChannelPipeline的ChannelHandler链拦截和处理的全过程:
下面对整个消息的处理和发送处理过程进行一个解释:
(1)先从左下方的开始:底层的SocketChannel.read()方法读取ByteBuf,然后触发ChannelRead事件,由IO线程NioEventLoop调用ChannelPipeline的fireChannelRead(Object msg)方法,将消息ByteBuf传输到ChannelPipeline中;
(2)消息依次经过HeadHandler、ChannelHandler1、ChannelHandler2…..TailHandler拦截和处理,在这个过程中,任何ChannelHandler都可以中断当前的流程,结束消息传递。
(3)调用ChannelHandlerContext的write()方法发送消息,消息从TailHandler开始,途径ChannelHandlerN….ChannelHandler1、HeadHandler,最终被添加到消息发送缓冲区,等待被发送到Channel中,在此过程中也可以中断消息的发送,比如编码失败的时候。
在netty中的事件分为inbound入站事件和outbound出站事件。inbound事件一般是由IO线程触发的,例如TCP链路建立事件、链路关闭事件、读事件、异常通知事件等,对应的是上图的左半部分。触发inbound事件的方法都是调用ChannelHandlerContext里面的方法,具体如下:
//channel注册事件
ChannelHandlerContext ChannelHandlerContext fireChannelRegistered();
//channel注销事件
ChannelHandlerContext ChannelHandlerContext fireChannelUnregistered();
//TCP链路建立成功,Channel激活事件
ChannelHandlerContext ChannelHandlerContext fireChannelActive();
//TCP连接关闭,链路不可用通知事件
ChannelHandlerContext ChannelHandlerContext fireChannelInactive();
//异常通知事件
ChannelHandlerContext ChannelHandlerContext fireExceptionCaught(Throwable cause);
//用户自定义事件
ChannelHandlerContext ChannelHandlerContext fireUserEventTriggered(Object evt);
//读事件
ChannelHandlerContext ChannelHandlerCont