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

Java基础

浏览数:77

2019-8-20

工作中可能经常会碰到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创建与构建的处理,后面再进行服务端启动的其它选项配置。

作者:Real_man