Pipeline & ChannelHandler for Netty_java

2015年去台湾第一天,台北做公交车准备去台北车站坐捷运去淡水。

Pipeline & ChannelHandler for Netty_java_02

台北街头,机车大军。

Pipeline & ChannelHandler for Netty_java_03

捷运站。


王皓的GitHub:https:///TenaciousDWang 

      


        今天来讲一下Netty中的两大组件Pipeline与ChannelHandler,我们之前写的例子,所有的逻辑都写在了ClientHandler与ServerHandler当中,通过判断数据包类型来执行不同的逻辑,现在指令数量不多,如果将来指令多时,我们需要写很多if,else,就会导致我们的逻辑处理器代码越来越臃肿,同时我们也注意到,每次编码解码时都要调用PacketCodeC类,这里我们也需要做相应的优化,Netty为我们提供这两大组件来解决问题,今天我们就来学习一下。


Pipeline & ChannelHandler for Netty_java_04


        先上结构图镇楼,Netty中,一个连接Connection对应一个Channel,所有的逻辑都在Channel中的Pipeline双向链表中。链表中每一个节点都是一个ChannelHandlerContext对象,这个对象是一个容量,里面包含一个ChannelHandler,该容器能拿到与Channel相关的上下文。


Pipeline & ChannelHandler for Netty_java_05


        ChannelHandler接口包含两个子接口ChannelInBoundHandler与ChannelOutBoundHandler,这两个子接口的核心方法分别为ChannelRead与Write,字面意思上一个负责读取,一个负责写入,他们的默认实现为两个Adapter类,接下来我们通过一段代码来做实验,看一看这两个类的传播路径。


        首先我们先创建三个Handler分别是A,B,C。他们分别继承ChannelInboundHandlerAdapter类,channelRead方法执行,打印信息到控制台,然后调用super父类的channelRead方法,会路由到下一个Handler执行channelRead方法。


Pipeline & ChannelHandler for Netty_java_06

Pipeline & ChannelHandler for Netty_java_07

Pipeline & ChannelHandler for Netty_java_08


        我们再服务端按照顺序添加这几个逻辑处理器,来运行一下看一下结果。


Pipeline & ChannelHandler for Netty_java_09

        

        打印顺序为A,B,C顺序执行,接下来我们看一下OutBound,同样我们创建三个Handler。


Pipeline & ChannelHandler for Netty_java_10

Pipeline & ChannelHandler for Netty_java_11

Pipeline & ChannelHandler for Netty_java_12


        并同样按照A,B,C的顺序添加到服务端的逻辑处理链。


Pipeline & ChannelHandler for Netty_java_13


        同样运行,打印顺序为C,B,A。与InBound正好相反,由此我们来画一张路,看一下事件传播的机制。


Pipeline & ChannelHandler for Netty_java_14


        虽然两个类都处于双向列表里,但是工作中两者并不互通,InBound通常只将事件传递给下一个InBound,OutBound通常只将事件传递给下一个OutBound,两者互不干扰。