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

Netty源码学习-ChannelHandler

发表于: 2013-12-25   作者:bylijinnan   来源:转载   浏览:
摘要: 一般来说,“有状态”的ChannelHandler不应该是“共享”的,“无状态”的ChannelHandler则可“共享” 例如ObjectEncoder是“共享”的, 但 ObjectDecoder 不是 因为每一次调用decode方法时,可能数据未接收完全(incomplete), 它与上一次decode时接收到的数据“累计”起来才有可能是完整的数据,是“有状态”的 p


一般来说,“有状态”的ChannelHandler不应该是“共享”的,“无状态”的ChannelHandler则可“共享”
例如ObjectEncoder是“共享”的, 但 ObjectDecoder 不是
因为每一次调用decode方法时,可能数据未接收完全(incomplete),
它与上一次decode时接收到的数据“累计”起来才有可能是完整的数据,是“有状态”的

public class SomePipelineFactory implements ChannelPipelineFactory {

	//共享
	private final StringEncoder stringEncoder = new StringEncoder(CharsetUtil.UTF_8);
	
	//定义成static的也可以
	//private static final StringEncoder stringEncoder = new StringEncoder(CharsetUtil.UTF_8);
	
    @Override
    public ChannelPipeline getPipeline() throws Exception {
        ChannelPipeline pipeline = Channels.pipeline();
		pipeline.addLast("stringEncoder", stringEncoder);
		
		//不共享
        pipeline.addLast("handler", new SomeHandler());
        return pipeline;
    }
}


因此,每一次ChannelPipelineFactory.getPipeline被调用时,
如果ChannelHandler是“不共享”的,则会新创建一个ChannelHandler的实例

ChannelPipelineFactory.getPipeline在以下方法中调用:


//NioServerSocketPipelineSink.Boss.registerAcceptedChannel
//SocketChannel(创建了pipeline):
private void registerAcceptedChannel(SocketChannel acceptedSocket, Thread currentThread) {

				//调用PipelineFactory.getPipeline
                ChannelPipeline pipeline =
                    channel.getConfig().getPipelineFactory().getPipeline();
				NioWorker worker = nextWorker();
                worker.register(new NioAcceptedSocketChannel(
                        channel.getFactory(), pipeline, channel,
                        NioServerSocketPipelineSink.this, acceptedSocket,
                        worker, currentThread), null);

}
	
//ServerBootstrap.bind	
//ServerSocketChannel(创建了pipeline):
public Channel bind(final SocketAddress localAddress) {

        ChannelPipeline bossPipeline = pipeline();
        bossPipeline.addLast("binder", binder);
        Channel channel = getFactory().newChannel(bossPipeline);
}



可见:
1.ServerSocketChannel与SocketChannel的pipeline实例不是同一个
每一个Channel都创建一个pipeline
2.ServerSocketChannel只有一个(如果同时绑定两个端口,例如同时提供80和443服务,则有两个)
与之关联的pipeline也只有一个,这pipeline里面的ChannelHandler只有“binder”(通常情况下)
3.SocketChannel会有多个:
socketChannelA--pipelineA(sharedHandler,newHandlerA0, newHandlerB0)
socketChannelB--pipelineB(sharedHandler,newHandlerA1, newHandlerB2)

socketChannelA和socketChannelB可能交由不同的workerThread来处理

因此如果ChannelHandler是“有状态”且“共享”,那就要注意线程同步的问题:

public class SharedHandler extends SimpleChannelUpstreamHandler  {
    
    private volatile int someState;
	//...
}


但查看org.jboss.netty.example.proxy.HexDumpProxyInboundHandler:
public class HexDumpProxyInboundHandler extends SimpleChannelUpstreamHandler {
    private volatile Channel outboundChannel;
	//...
}

public ChannelPipeline getPipeline() throws Exception {
        ChannelPipeline p = pipeline(); // Note the static import.
        p.addLast("handler", new HexDumpProxyInboundHandler(cf, remoteHost, remotePort));
        return p;
    }


不是很理解,照理说,HexDumpProxyInboundHandler是“不共享”的,应该不存在
线程同步的问题,但为什么outboundChannel要定义成“volatile”呢?

Netty源码学习-ChannelHandler

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
netty里面最重要的应该是ChannelHandler,这个里面也是用户编程直接打交道的接口,也是串行于Channe
netty里面最重要的应该是ChannelHandler,这个里面也是用户编程直接打交道的接口,也是串行于Channe
channelHandler 在Netty 4.x版本有了相当大的改动 http://netty.io/wiki/new-and-noteworthy.html
本章介绍 ChannelPipeline ChannelHandlerContext ChannelHandler Inbound vs outbound(入站和出站)
背景 最忌工作中接触到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的原理及结构,下面几篇文章我们开始
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号