美文网首页程序员
Netty服务端启动-Channel的创建与初始化

Netty服务端启动-Channel的创建与初始化

作者: Real_man | 来源:发表于2019-01-08 18:25 被阅读109次

    工作中可能经常会碰到Netty相关程序的处理,但是很多时候都是知其然不知其所以然,阅读其源码是一个很好的方式加深自己对程序的理解,而且Netty本身也是一个非常优秀的异步编程框架,读大师的代码,是很好的成长方式

    先从Netty服务端启动的程序开始看:

    服务端Netty代码

    一般服务端代码如下:

     EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try {
                ServerBootstrap b = new ServerBootstrap();
                // 服务端的BootStrap,一个需要接受连接,一个用来处理事件
                b.group(bossGroup, workerGroup)
                        // Channel理解为通道,网络传输的通道类型
                        .channel(NioServerSocketChannel.class)
    
                        // ChannerlHandler要被装进ChannelPipeline
                        // 而过程则是调用ChannelInitializer的iniChannel方法
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch)
                                    throws Exception {
                                // addLast,在PipeLine中的Handler是有顺序的,所以
                                // 有addLast,addFirst等方法
                                // 添加的同时,可以指定Encoder和Decoder
                                ch.pipeline().addLast(new RequestDecoder(),
                                        new ResponseDataEncoder(),
                                        new ProcessingHandler());
                            }
                        }).option(ChannelOption.SO_BACKLOG, 128)
                        .childOption(ChannelOption.SO_KEEPALIVE, true);
    
                ChannelFuture f = b.bind(port).sync();
                f.channel().closeFuture().sync();
            } finally {
                workerGroup.shutdownGracefully();
                bossGroup.shutdownGracefully();
            }
    

    分析

    1. Channel的创建
      ServerBootStrap.bind -> doBind(SocketAddress) -> initAndRegister() ->
      channel = channelFactory.newChannel();

    在ServerBootStrap中的initAndRegister方法里,channel是通过ChannelFactory进行创建的。

    1. ChannelFactory的设置,既然Channel通过ChannelFactory创建的,那么ChannelFactory是在哪里设置的呢?

    点击ChannelFactory可以看到如下使用ChannelFactory的地方,在116行的地方有。


    image.png

    另外在我们的程序之中,只有channel方法设置了Channel:然后往下看
    ServerBootStrap.channel(Class<? extends C> channelClass)
    -> channelFactory(new ReflectiveChannelFactory<C>(channelClass))
    -> channelFactory(ChannelFactory<? extends C> channelFactory)
    -> this.channelFactory = channelFactory;

    1. Channel的初始化操作,创建Channel之后我们可以看到在ServerBootStrap中对其调用init(channel)方法。
    image.png image.png
    1. 在init方法处理Channel之前,我们看一下Channel的构造方法,因为我们传的是NioServerSocketChannel.class,看一下它的构造方法
    image.png

    这不是NIO编程常看到的:
    DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider()
    -> newSocket(SelectorProvider provider)
    ->provider.openServerSocketChannel()

    image.png

    ->


    image.png

    ->


    image.png

    最终在NioServerSocketChannel中:

    • ch: provider.openServerSocketChannel()
    • readInterestoP: SelectionKey.OP_ACCEPT
    • id:DefaultChannelId.newInstance()
    • unSafe: new NioMessageUnsafe()
    • pipeLine: new DefaultChannelPipeline(this)
    • config: new NioServerSocketChannelConfig(this, javaChannel().socket())

    到这里是完成了channel的构造工作。

    1. 另外看一下ServerBootStrap的config属性。


      image.png

    最后

    这里先看ServerBootStrap的channel创建与构建的处理,后面再进行服务端启动的其它选项配置。

    相关文章

      网友评论

        本文标题:Netty服务端启动-Channel的创建与初始化

        本文链接:https://www.haomeiwen.com/subject/ebmbrqtx.html