ChannelPipeline

Channel 将数据管道抽象为ChannelPipeline

ChannelPipeline 是Channel 的数据管道,也是ChannelHandler 的容器,Channel 产生的基本事件都会交给ChannelPipeline,接着ChannelHandler 链会拦截和处理这些事件,我们先来看一段设置ChannelHandler 的代码

Bootstrap b = new Bootstrap();
b.handler(new ChannelInitializer() {            
        @Override            
        protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline()
                        .addLast(new LengthFieldBasedFrameDecoder(22, 0, 4, 0, 4, false))
                        .addLast(new MessageToByteEncoder() {
                            @Override
                            protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) throws Exception {
                                byte[] data = msg.getBytes();
                                out.writeInt(data.length).writeBytes(data);
                            }
                        })
                        .addLast(new StringDecoder())
                        .addLast(new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                for (int i = 0; i < 100; i++) {
                                    ctx.channel().writeAndFlush("Hello Server Day" + i);
                                }
                            }
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                System.out.println(msg);
                            }
                        });
            }
        });

抽取ChannelPipeline 添加ChannelHandler 的代码简化后

ch.pipeline()
        .addLast(new LengthFieldBasedFrameDecoder(22, 0, 4, 0, 4, false))
        .addLast(new MessageToByteEncoder(){...})
        .addLast(new StringDecoder())
        .addLast(new ChannelInboundHandlerAdapter() {...});

用户不需要自己创建pipeline,ServerBootstrap 或者Bootstrap 会为每一个Channel 连接创建一个独立的pipeline。对于使用者而言,只需要将自定义的拦截器加入到pipeline 中即可,上面的代码就是把ChannelHandler 加入到pipeline 的ChannelHandler 链中。

ChannelPipeline 处理的基本事件

总的来说有两种事件,inbound 和 outbound。

ChannelPipeline_第1张图片
ChannelPipeline 处理的基本事件

ChannelHandler 链及拦截处理事件过程

ChannelPipeline 维护着一条ChannelHandler 链表,并提供增删改查等方法来修改这些方法,从如下的基本方法可以看出,链表可以随便添加,删除,还可以指定位置添加或删除。

ChannelPipeline 的基本方法
addFirst
addLast
addBefore
addAfter
addFirst
addLast
remove
removeFirst
removeLast
replace
first
firstContext
last
lastContext
get

ChannelHandler 链的头是连接着Channel,相当于连着着网络外部。ChannelHandler 链的尾是连接着自己的程序的,相当于本身自己。当产生一个inbound 事件(入境事件),就是说外部有东西要进来了,就是Channel 有东西进来了。所以是从头部到尾部的处理顺序。反之,我们需要发送一条消息处理,就会产生一个outbound 事件,就是说我们需要发送东西给网络外部,就是从尾部到头部的处理顺序。处理的过程中,任何一个处理器把事件挂起都会中断事件的传递,就是说被一个ChannelHandler 都有能力拦截事件,和传递事件到下个ChannelHandler 的能力。

你可能感兴趣的:(ChannelPipeline)