关于Netty Pipeline中Handler的执行顺序问题

原文地址:http://blog.csdn.net/wgyvip/article/details/25637651

最近在学习Netty框架,根据官网的教程学着做了几个小测试,都成功了,后面开始试着写自己的应用的时候出了问题:Server发出的数据到达Client之后一直解码失败,折腾了好久,对比着官方的实例代码一步步走,最后终于在ChannelInitializer中发现了问题。原来我是这样写的:

[java] view plain copy
 
  1. pipeline.addLast("StringDecoder", new StringDecoder(Charset.forName("UTF-8")));  
  2.    pipeline.addLast("ServerHandler", new ServerHandler());  
  3.    pipeline.addLast("StringEncoder", new StringEncoder(Charset.forName("UTF-8")));  

官网的教程是这样写的:

[java] view plain copy
 
  1. pipeline.addLast("StringDecoder", new StringDecoder(Charset.forName("UTF-8")));  
  2. pipeline.addLast("StringEncoder", new StringEncoder(Charset.forName("UTF-8")));  
  3. pipeline.addLast("ServerHandler", new ServerHandler());  

注意到Handler在Pipeline中的顺序不一样。在Netty文档里看到Handler在Pipeline中的执行顺序是InboundHandler顺序执行,OutboundHandler逆序执行,我原以为所谓的你须执行会从Pipeline的最后一项开始执行,所以讲所有的OutboundHandler都放在了最后,为了看着方便,其实不是这样的。在InboundHandler执行完成需要调用Outbound的时候,比如ChannelHandlerContext.write()方法,Netty是直接从该InboundHandler返回逆序的查找该InboundHandler之前的OutboundHandler,并非从Pipeline的最后一项Handler开始查找,是我的理解错了。

 

channelRead与channelRead0的区别:

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        boolean release = true;
        try {
            if (acceptInboundMessage(msg)) { // 判定msg类型是否与当前handler需要处理的消息类型一致,一致的话就条用channelRead0进行处理,否则提交到下一个handler
                @SuppressWarnings("unchecked")
                I imsg = (I) msg;
                channelRead0(ctx, imsg); // channelRead0进行处理
            } else {
                release = false;
                ctx.fireChannelRead(msg); // 跳转到下一个handler
            }
        } finally {
            if (autoRelease && release) {
                ReferenceCountUtil.release(msg);
            }
        }
    }

 

posted @ 2018-02-28 23:06  bf378  阅读(804)  评论(0编辑  收藏  举报