zoukankan      html  css  js  c++  java
  • netty4 ServerBootstrap.bind(port) debug

    代码是netty4自带的例子

    我们在bind的行前加个断电,下面是ServerBootstrap.bind(port)方法所经历的一些步骤。

     

    在AbstractBootstrap.initAndRegister()中实例化一个Channel并进行初始化配置。

    (可以参考《Netty4 initAndRegister 解析》)

    配置项为在初始化Bootstrap时我们传入的handlers和一些设置。

    下面进行channel的初始化(可以参考《Netty 源码分析之 一 揭开 Bootstrap 神秘的红盖头 (客户端)》)

    注意箭头所示,这里的channelFactory是ReflectiveChannelFacotry.

    这里就返回一个NioServerSocketChannel类型的channel.

    下面的init(channel)对刚生成的channel进行一些初始化配置。

    接着往下看:

    注意下面注释内容。这里有两个添加handler的动作,后面一个时延时的,为了确保所有的handler都被放置在ServerBootstrapAccepter之前。这时候就已经初始化完channle中的eventloop对象了,可以使用eventloop来执行该channel的一些工作。

    初始化完channel之后:反回到initAndRegister()先看一下eventloop注册到channel。

    EventLoop注册Channel

     

    说白了就是获取一个线程来处理这个注册事件。

     

    那么这个EventExecutor到底是什么?我们获得了这个EventExecutor之后我们进入它的register(channel)方法看看:

     

    这里注意到,eventloop注册channel实际上是channel注册eventoloop。最终将当前的eventloop传入到channel中作为channel的属性。

    这里返回unsafe对象。其实 unsafe 特别关键, 它封装了对 Java 底层 Socket 的操作, 因此实际上是沟通 Netty 上层和 Java 底层的重要的桥梁

    下面的eventLoop.inEvenLoop()判断该eventloop线程是否当前线程。这里关于eventloop的内容要以《Netty4 initAndRegister 解析》为主,下面的内容总结的一般。

    然后下面的doregister0调用的是AbstractChannel在子类中的实现。比如当前是NioServerSocketChannel.doBind()同样也是在这个子类中实现的。

    下面这快是对EventLoop接口的分析。

    最后我们进入这个loop线程的执行线程:

    先到此为止我们继续上面的逻辑:

    以上都是initAndRegister()方法中的逻辑。

    接着往下走:

    DefaultChannelPipeline{(LoggingHandler#0 = io.netty.handler.logging.LoggingHandler), (ServerBootstrap$ServerBootstrapAcceptor#0 = io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor)}

     

    继续主流程:

    这里同时要留意eventloop的用法。

    Netty内部都是通过线程在处理各种数据,EventLoopGroup就是用来管理调度他们的,注册Channel,管理他们的生命周期,下面就来看看EventLoopGroup是怎样工作的。

    EventLoops的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。
    EventLoopGroup会包含多个EventLoop。
    参考:http://www.tuicool.com/articles/mEJvYb

    最终还是到channel.bind(...)这个方法来绑定。

    下面进入:final AbstractChannelHandlerContext next = findContextOutbound();

    EventExecutor executor = next.executor();

    前面将eventloop注册到channel中之后,这里取出channel的eventloop。

     AbstractChannelHandlerContext这个东西有专门博文。

    一直循环到ctx.outbound为true的时候,获取这个ctx。

    还记得那个上行下行的图吗,这就是那里的感念。

    下面进入到EventExecutor executor = next.executor();方法:有上图可知当前的executor属性为null。

    我们进入channel().eventloop().这个地方需要返回一个EventExecutor类型的对象。

    我们先看channel方法:

    pipeline=DefaultChannelPipeline{(LoggingHandler#0 = io.netty.handler.logging.LoggingHandler), (ServerBootstrap$ServerBootstrapAcceptor#0 = io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor)}

    这里的(LoggingHandler#0 = io.netty.handler.logging.LoggingHandler)是什么鬼?

    还记得上面的init(channel)吗,我们在那里添加了handler和ServerBootstrapAccepter

    下面我们还会涉及到这个handler。

    先不管我们先进入pipeline.channel();方法

    return channel().eventLoop();这里执行完channel()方法后我们进入eventloop()方法:
    这里需要返回一个EventExecutor类型的对象。

    然而这里返回的却是一个NioEventLoop类型的对象。我们在看一下关系图:

    先不管我们接着看:下面进入父类的方法:

    最终我们执行完了这个方法,返回一个EventLoop类型的对象。

    NioEventLoop类型的对象怎么会是EventExecutor类型呢?

    通过NioEventLoop类型检索我们发现

    原来EventLoop继承了EventExecutor接口。没办法社区办idea功能比较简陋,就不画类型关系图了。

    那么我们接着netty流程往下走:

    在下面这个方法这里循环所有的handler的bind()方法。

    这里的handler:LoggingHandler。还记得上面的疑问吗。答案在这里。

     当前的handler是LoggingHandler那么我们就进入到:

    这里又一个非常值得注意的地方。LoggingHandler的bind()方法并没有写什么业务逻辑,只打印了个日志:

    18:33:33.694 [nioEventLoopGroup-2-1] INFO  i.n.handler.logging.LoggingHandler - [id: 0x62c8b900] BIND: 0.0.0.0/0.0.0.0:8007

    然后直接调用了下一个handler的bind()方法。

    这个bind()方法是定义在ChannelOutboundHandler中的方法。

    所有我们就行入到下一次循环中了:

    开始循环了。

     下一个handler:

     到这里终于跳出netty框架到老nio层了!

    但是到这的时候程序没进入bind直接跳出来了:

    这里成功了?

     我们专门打个断点到那个nio bind的地方。根据以上的流程分析我们知道最终的nio层bind就在我们非常熟悉的NioServerSocketChannel中实现。

    我们手动进入这个类中找到bind方法:

    这就和我们平时直接用nio写业务时一样了:

  • 相关阅读:
    单例模式
    HashSet、LinkedHashSet、SortedSet、TreeSet
    ArrayList、LinkedList、CopyOnWriteArrayList
    HashMap、Hashtable、LinkedHashMap
    andrew ng machine learning week8 非监督学习
    andrew ng machine learning week7 支持向量机
    andrew ng machine learning week6 机器学习算法理论
    andrew ng machine learning week5 神经网络
    andrew ng machine learning week4 神经网络
    vue组件监听属性变化watch方法报[Vue warn]: Method "watch" has type "object" in the component definition. Did you reference the function correctly?
  • 原文地址:https://www.cnblogs.com/guazi/p/6586252.html
Copyright © 2011-2022 走看看