zoukankan      html  css  js  c++  java
  • Netty源码分析第1章(Netty启动流程)---->第3节: 服务端channel初始化

     

    Netty源码分析第一章:Netty启动流程

     

    第三节:服务端channel初始化

     

    回顾上一小节的initAndRegister()方法:

    final ChannelFuture initAndRegister() {
        Channel channel = null;
        try {
            //创建channel
            channel = channelFactory.newChannel();
            //初始化channel
            init(channel);
        } catch (Throwable t) {
            //忽略非关键代码
        }
        ChannelFuture regFuture = config().group().register(channel);
        //忽略非关键代码
        return regFuture;
    }

    简单回顾上一小节内容, 我们跟完了创建channel的步骤, 知道了Netty的NioServerSocketChannel和jdk的ServerSocketChannel之间的关系, NioServerSocketChannel和jdk的channel是组合关系, 在其父类AbstractChannel中有jdk的channel的一个成员变量, 通过创建netty的channel为jdk的channel赋值

     

    我们继续往下看init(Channel)方法

    因为是ServerBootstrap对象调用的init()方法, 所以我们跟到ServerBootstrap类的init()方法中:

    void init(Channel channel) throws Exception {
        //获取用户定义的选项(1)
        final Map<ChannelOption<?>, Object> options = options0();
        synchronized (options) {
            channel.config().setOptions(options);
        }
    
        //获取用户定义的属性(2)
        final Map<AttributeKey<?>, Object> attrs = attrs0();
        synchronized (attrs) {
            for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
                @SuppressWarnings("unchecked")
                AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
                channel.attr(key).set(e.getValue());
            }
        }
        //获取channel的pipline(3)
        ChannelPipeline p = channel.pipeline();
        //work线程组(4)
        final EventLoopGroup currentChildGroup = childGroup;
        //用户设置的Handler(5)
        final ChannelHandler currentChildHandler = childHandler;
        final Entry<ChannelOption<?>, Object>[] currentChildOptions;
        final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
        //选项转化为Entry对象(6)
        synchronized (childOptions) { 
            currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));
        }
        //属性转化为Entry对象(7)
        synchronized (childAttrs) { 
            currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));
        }
        //添加服务端handler(8)
        p.addLast(new ChannelInitializer<Channel>() {
            //初始化channel
            @Override
            public void initChannel(Channel ch) throws Exception {
                final ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = config.handler();
                if (handler != null) { 
                    pipeline.addLast(handler);
                } 
                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() { 
                        pipeline.addLast(new ServerBootstrapAcceptor(
                                currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });
    }

    初看起来代码好长, 其实并不复杂, 这里对每一步进行一个简述:

    步骤(1), (2)是获取的用户代码中定义的选项和属性

     

    步骤(3)是获取channel的pipeline, 这个channel就是上一小节我们学习创建的NioServerSocketChannel, 我们知道每个channel都有个pipeline的属性, 是AbstractChannel的成员变量, 而这里的pipeline()就是获取其与channel绑定的pipeline, 这个pipline, 会在后面的章节中讲到

     

    步骤(4)是获取worker线程组, 我们知道这个worker线程组就是在用户代码中创建的NioEventLoopGroup, 后来在ServerBootstrap的group()方法中赋值为ServerBootstrap的成员变量, 而这里是获取其成员变量, 并赋值到局部变量currentChildGroup中, NioEventLoop相关知识会在后面的章节讲到

     

    步骤(6), (7)是将选项和属性转化成Entry对象

     

    步骤(8)是添加服务端Handler, 是通过和channel绑定的pipeline调用addLast()方法进行添加, 传入一个ChannelInitializer类的子类对象, 至于addLast方法是做什么的, ChannelInitializer是做什么的, 后绪章节都会给大家详细剖析, 这里不必深究

     

    这一小节我们了解了有关channel初始化的过程, 我们目前只需了解其大概步骤, 有关addLast的逻辑会在后面的章节进行详细剖析

     
    上一节: NioServerSocketChannel的创建

    下一节: 注册多路复用

  • 相关阅读:
    C++成员变量与函数内存分配
    Sqlite ContentProvider Loader 上下文 对话框
    好书好人生--读书的步骤
    小智慧40
    流媒体开发之-直播界面切换电视台频道
    HDU 4617Weapon(两条异面直线的距离)
    BON取代半岛电视,美国人要“换口味”了吗?
    【Todo】Lucene系统学习
    Zookeeper学习 & Paxos
    C++中的虚继承 & 重载隐藏覆盖的讨论
  • 原文地址:https://www.cnblogs.com/xiangnan6122/p/10202646.html
Copyright © 2011-2022 走看看