Netty之服务启动且注册成功之后

1,679 阅读3分钟

「我正在参与掘金会员专属活动-源码共读第一期,点击参与

前言

一直大大咧咧, 有点健忘, 万万没想到, 这次写文章也健忘了, 之前我们分析Netty的启动流程讲了初始化和注册, 但是初始化和注册成功之后的doBind0()方法给忘的一干二净...

image.png

浅浅回顾一下:

  • Netty自定义启动类MyServer中执行了ServerBootstrap.bind(port).sync()方法启动Netty
  • bind()方法的具体实现doBind()方法中先是执行了initAndRegister()方法, 对channel进行了初始化和注册
  • 当初始化和注册完成之后就会执行到doBind0()方法

如果可以的话, 大家最好是去看一下我之前的几篇文章了解一下整体流程:

doBind0()方法

image.png

在这个方法中, 我们可以看到, 他就是channle.eventLoop()执行了一个Runnable

channle.eventLoop() 方法

image.png

channle.eventLoop()方法是一个多态, 执行的是AbstractChannel类下的方法, 在这个方法中可以看到, 他就是对eventLoop进行了赋值并返回, 至于这个this.eventLoop的初始化是在register 的时候

Netty服务端启动流程分析 - 掘金 (juejin.cn)

image.png

// 简单代码如下
@Override
    public final void register(EventLoop eventLoop, final ChannelPromise promise) {
        ....
        AbstractChannel.this.eventLoop = eventLoop;
        ...
    }	

image.png

通过我们打断点可以发现eventLoop的类型是NioEventLoop, 继承关系图如下所示

image.png

image.png

通过断点我们可以看到具体的执行过程就是进入到execute方法. 然后判断task是否为空, 不为空就进入最后的execute方法

image.png

在这个方法内部执行流程:

  • 判断当前线程是否为eventLoop线程
  • 将任务添加到taskQueue队列

image.png

addTask()方法详情, offerTask()方法的作用就是添加任务, 并返回是否添加成功, 如果添加失败, 就拒绝执行处理器

channel.bind()

接下来我们回到doBind0方法, 继续往下分析

image.png

channelNioServerSocketChannel类, 而bind方法的实现类是在AbstractChannel里面

image.png

image.png

调用的是pipeline.bind()pipeline它链接了ChannelHandlerContext,head是outbound,tail是inbound.

image.png

继续往下走 ,他会执行tail.bind()方法, 进入到AbstractChannelHandlerContextbind()方法

image.png

如果你看过我上一篇文章, 就会有很熟悉的感觉, findContextOutbound方法, 我们在上一篇文章有说

image.png

执行完findContextOutbound()方法之后, 也是我们熟悉的一部分, 已经讲过很多次了

image.png

next.invokeBind(localAddress, promise);方法就是执行回调的

端口绑定的发生

image.png

再次进入这个方法

image.png

pipeline.head就是outbound, 所以在这里的时候会执行DefaultChannelPipeline.bind()方法

image.png

再往下走

image.png

我们到了AbstractChannel类的bind方法, 直接看doBind(), 打断点跳转

image.png

在这里就是执行了 JDK 原生的bind()方法来绑定端口信息, 至此, 我们的Netty启动系列终于算是差不多完结了, 吗?

下一篇文章开始继续攻克任务三, 为什么创建的channel是非阻塞的




本文内容到此结束了

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

我是 宁轩 , 我们下次再见