Netty 源码分析2---事件注册过程

  • 示例代码
package com.demo.study1.socket.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

public class EchoServer {
    public static void main(String[] args) throws Exception {
        Integer PORT = 8088;

        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 100)
                    .handler(new LoggingHandler(LogLevel.DEBUG))
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new EchoServerHandler());
                        }
                    });

            // Start the server.
            ChannelFuture f = b.bind(PORT).sync();
            // Wait until the server socket is closed.
            //阻塞主线程,直到网络服务被关闭
            f.channel().closeFuture().sync();
        } finally {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

}

从bind方法debug进入

这里的initAndRegister是创建/初始化ServerSocketChannel对象,并注册到Seletor

这里需要看下这个init方法(初始化通道的参数,网络参数,自定义的参数等),这个方法中有下面一段代码

  //ChannelInitializer是一个特殊的处理器,一般在registerd之后,执行一次,然后销毁,用于初始化channel
   p.addLast(new ChannelInitializer<Channel>() {//添加处理器
            @Override
            public void initChannel(final Channel ch) throws Exception {
                final ChannelPipeline pipeline = ch.pipeline();
                ChannelHandler handler = config.handler();//获取配置中的handler
                if (handler != null) {
                    pipeline.addLast(handler);
                }

                ch.eventLoop().execute(new Runnable() {
                    @Override
                    public void run() {
                        pipeline.addLast(new ServerBootstrapAcceptor(//添加新的ServerBootstrapAcceptor
                                ch, currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                    }
                });
            }
        });

这里配置中的handler就是最前面示例中的LoggingHandler,添加之前只有头处理器和尾处理器

添加之后:添加多了serverbootstrap匿名实现类

进入注册方法

根据选择器,选择一个合适的NioEventLoop进行注册

断点打到register0方法,进入该方法(因为EvenLoop默认是不执行的,只有当有任务提交才会执行,所以他会以任务提交的方式执行)

这里就是在注册channel了

注册完成之后,这里在添加handler,进入方法

这里在添加最前面示例中的LoggingHandler

这里添加完LoggingHandler之后将ServerBootstrapAcceptor移除了

移除之后的只有头日志和尾三个了

 

传播完成注册事件

这是一个头处理器,什么都不做,只是传播事件。(就是找到下一个入站事件)

这里是传播到LoggingHandler

记录日志,继续传播事件

继续找入站事件

如果不是入站事件就一直往下找

这里找到的尾处理器了

他的实现是一个空,事件传播到此为止。register就到此结束了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值