当前位置:首页 > 开发 > 编程语言 > 网络编程 > 正文

Netty源码学习-DefaultChannelPipeline2

发表于: 2013-12-11   作者:bylijinnan   来源:转载   浏览:
摘要: Netty3的API http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/ChannelPipeline.html 里面提到ChannelPipeline的一个“pitfall”: 如果ChannelPipeline只有一个handler(假设为handlerA)且希望用另一handler(假设为handlerB) 来
Netty3的API
http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/ChannelPipeline.html
里面提到ChannelPipeline的一个“pitfall”:
如果ChannelPipeline只有一个handler(假设为handlerA)且希望用另一handler(假设为handlerB)
来取代handlerA去完成剩下的工作,那就要先add handlerB再remove handerA:


Pitfall

Due to the internal implementation detail of the current default ChannelPipeline, the following code does not work as expected if FirstHandler is the last handler in the pipeline:

 public class FirstHandler extends SimpleChannelUpstreamHandler {

     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
         // Remove this handler from the pipeline,
         ctx.getPipeline().remove(this);
         // And let SecondHandler handle the current event.
         ctx.getPipeline().addLast("2nd", new SecondHandler());
         ctx.sendUpstream(e);
     }
 }
 


正确的做法是
        ctx.getPipeline().addLast("2nd", new SecondHandler());
ctx.getPipeline().remove(this);

我的测试代码:
https://github.com/bylijinnan/nettyLearn/tree/master/ljn-netty3-learn/src/main/java/com/ljn/handler/pitfall

这是为什么呢?

问题出在ctx.sendUpstream(e):

public class DefaultChannelPipeline implements ChannelPipeline {

    private final class DefaultChannelHandlerContext implements ChannelHandlerContext {

		public void sendUpstream(ChannelEvent e) {
			
			//下面的this是DefaultChannelHandlerContext
            DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
            if (next != null) {
                DefaultChannelPipeline.this.sendUpstream(next, e);
            }
        }
	}
	
}
		


当ChannelPipe只有一个handler(也就是只有一个ChannelHandlerContext,代码中的ctx)时,
ctx.next = null
在sendUpstream方法的
DefaultChannelHandlerContext next = getActualUpstreamContext(this.next);
返回的next=null,没有继续往下执行
因此Upstream的处理就中断了

不熟悉ChannelPipeline流程的可以先看看这篇文章: http://bylijinnan.iteye.com/blog/1981763

Netty源码学习-DefaultChannelPipeline2

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
背景 最忌工作中接触到Netty相关应用场景,之前看过mima的部分源码,所以最近看了Netty的部分源码和
类结构图: 不了解Executor接口原理的可以查看concurrent包中的api介绍,这里只介绍Netty中EventExe
Transport API的核心: Channel接口 类图表示Channel含有Pipeline和Config接口,pipeline上一节有所
Netty是一个基于JAVA NIO类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、
先看下netty的channel对象关联关系。channel是由channelfactory来创建的,channelfactory又分为clie
感谢网友【黄亿华】投递本稿。 上一篇文章我们概要介绍了Netty的原理及结构,下面几篇文章我们开始
上一篇文章我们概要介绍了Netty的原理及结构,下面几篇文章我们开始对Netty的各个模块进行比较详细
netty里面最重要的应该是ChannelHandler,这个里面也是用户编程直接打交道的接口,也是串行于Channe
本文采用版本为Jboss Netty-3.2.4.Final,Jboss Netty示例example、几十页的user guide是快速学习的
本文为原创,转载请注明出处 netty 4源码分析-write Netty的写操作由两个步骤组成: Write:将msg存
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号