大纲
1.Pipeline和Handler的作用和构成
2.ChannelHandler的分类
3.几个特殊的ChannelHandler
4.ChannelHandler的生命周期
5.ChannelPipeline的事件处理
6.关于ChannelPipeline的问题整理
7.ChannelPipeline主要包括三部分内容
8.ChannelPipeline的初始化
9.ChannelPipeline添加ChannelHandler
10.ChannelPipeline删除ChannelHandler
11.Inbound事件的传播
12.Outbound事件的传播
13.ChannelPipeline中异常的传播
14.ChannelPipeline总结
1.Pipeline和Handler的作用和构成
(1)Pipeline和Handler的作用
(2)Pipeline和Handler的构成
(1)Pipeline和Handler的作用
可以在处理复杂的业务逻辑时避免if else的泛滥,可以实现对业务逻辑的模块化处理,不同的逻辑放置到单独的类中进行处理。最后将这些逻辑串联起来,形成一个完整的逻辑处理链。
Netty通过责任链模式来组织代码逻辑,能够支持逻辑的动态添加和删除,能够支持各类协议的扩展。
(2)Pipeline和Handler的构成
在Netty里,一个连接对应着一个Channel。这个Channel的所有处理逻辑都在一个叫ChannelPipeline的对象里,ChannelPipeline是双向链表结构,它和Channel之间是一对一的关系。
ChannelPipeline里的每个结点都是一个ChannelHandlerContext对象,这个ChannelHandlerContext对象能够获得和Channel相关的所有上下文信息。每个ChannelHandlerContext对象都包含一个逻辑处理器ChannelHandler,每个逻辑处理器ChannelHandler都处理一块独立的逻辑。
2.ChannelHandler的分类
ChannelHandler有两大子接口,分别为Inbound和Outbound类型:第一个子接口是ChannelInboundHandler,用于处理读数据逻辑,最重要的方法是channelRead()。第二个子接口是ChannelOutboundHandler,用于处理写数据逻辑,最重要的方法是write()。
这两个子接口默认的实现分别是:ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter。它们分别实现了两个子接口的所有功能,在默认情况下会把读写事件传播到下一个Handler。
InboundHandler的事件通常只会传播到下一个InboundHandler,OutboundHandler的事件通常只会传播到下一个OuboundHandler,InboundHandler的执行顺序与实际addLast的添加顺序相同,OutboundHandler的执行顺序与实际addLast的添加顺序相反。
Inbound事件通常由IO线程触发,如TCP链路的建立事件、关闭事件、读事件、异常通知事件等。其触发方法一般带有fire字眼,如下所示:
ctx.fireChannelRegister()、
ctx.fireChannelActive()、
ctx.fireChannelRead()、
ctx.fireChannelReadComplete()、
ctx.fireChannelInactive()。
Outbound事件通常由用户主动发起的网络IO操作触发,如用户发起的连接操作、绑定操作、消息发送等操作。其触发方法一般如:ctx.bind()、ctx.connect()、ctx.write()、ctx.flush()、ctx.read()、ctx.disconnect()、ctx.close()。
3.几个特殊的ChannelHandler
(1)ChannelInboundHandlerAdapter
(2)ChannelOutboundHandlerAdapter
(3)ByteToMessageDecoder
(4)SimpleChannelInboundHandler
(5)MessageToByteEncoder
(1)ChannelInboundHandlerAdapter
ChannelInboundHandlerAdapter主要用于实现ChannelInboundHandler接口的所有方法,这样我们在继承它编写自己的ChannelHandler时就不需要实现ChannelHandler里的每种方法了,从而避免了直接实现ChannelHandler时需要实现其所有方法而导致代码显得冗余和臃肿。
[code]//Handles an I/O event or intercepts an I/O operation, and forwards it to its next handler in its ChannelPipeline.public interface ChannelHandler { //Gets called after the ChannelHandler was added to the actual context and it's ready to handle events. void handlerAdded(ChannelHandlerContext ctx) throws Exception; //Gets called after the ChannelHandler was removed from the actual context and it doesn't handle events anymore. void handlerRemoved(ChannelHandlerContext ctx) throws Exception; //Gets called if a Throwable was thrown. @Deprecated void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception; //Indicates that the same instance of the annotated ChannelHandler can be added to one or more ChannelPipelines multiple times without a race condition. @Inherited @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface Sharable { // no value }}//Skeleton implementation of a ChannelHandler.public abstract class ChannelHandlerAdapter implements ChannelHandler { // Not using volatile because it's used only for a sanity check. boolean added; //Return true if the implementation is Sharable and so can be added to different ChannelPipelines. public boolean isSharable() { Class clazz = getClass(); Map |