Netty进阶:手把手教你如何编写一个NIO服务端

技巧提示:基于Future异步编程,在主线程中通过调用future.isDone方法判断异步方法是否已完成,如果未完成,通过在该凭证上添加监听器(事件回调),操作完成后执行回调逻辑。

从上面的方法来看服务端的绑定流程包含初始化与绑定两个子流程,接下来将分别深入探讨。

2.1 通道初始化

基于NIO编程,需要先创建通道,然后将其注册到事件选择器,这个过程由 AbstractBootstrap 的 initAndRegister 方法实现。

在这里插入图片描述

实现的关键点如下:

代码@1:创建NIO服务端通道实现类NioServerSocketChannel的实例。

代码@2:调用 init 方法初始化通道。

代码@3:将通道注册到事件轮询器EventLoopGroup

代码@4::如果通道已注册,但发生了错误则调用通道close方法回收相关资源,如果未注册成功,则强制清除通道占用的资源,特别是文件占用符。

关于通道的注册逻辑已经在手把手教你如何编写一个NIO客户端 中已详细介绍,故接下来重点关注一下服务端通道的注册流程。

2.1.1 服务端通道初始化流程

AbstractBootstrap 的 init 方法是一个抽象方法,具体有其子类实现:

在这里插入图片描述

服务端通道的初始化代码由ServerBootstrap的init方法。

在这里插入图片描述

Step1:首先将通过ServerBootstrap设置的选项与附加选项初始化到通道中。

在这里插入图片描述

Step2:init 方法的关键点:将 handler 方法设置的事件链,同时新增 ServerBootstrapAcceptor 事件处理方法加入到 NioServerSocketChannel 的事件链,但并没有把 childHandler 中添加的事件链添加到NioServerSocketChannel。

读者朋友们,请停下来思考一下,为什么会这样?从现在可以肯定的是 handler 方法定义的事件处理方法将在与 NioServerSocketChannel 相关的事件发生时其作用。

要解开这个谜题,我们有必要来看看 ServerBootstrapAcceptor 是如何工作的。

2.1.2 ServerBootstrapAcceptor 详解

ServerBootstrapAcceptor 类图如下所示:

在这里插入图片描述

ServerBootstrapAcceptor方法只实现了inbound事件的channelRead事件。在详细探究它之前先看看属性:

  • EventLoopGroup childGroup

事件执行器组,ServerBootstrap设置的从Reactor线程组,即Work线程组。

  • ChannelHandler childHandler

ServerBootstrap#childHandler 设置的事件处理器,也就是用户定义的事件处理器。

接下来探究其 channelRead 方法的实现逻辑:

在这里插入图片描述

Step1:channelRead竟然传入的是一个Channel,那这个Channel对象是NioSocketChannel吗?

是的,原来当 OP_ACCEPT 事件触发后,Server端会通过调用ServerSocketChannel 的 accept()方法,将返回一个 NioSocketChannel,读写操作的载体,在NIO中负责数据的读写。

Step2:将通过 childHandler 定义的事件处理器绑定到 NioSocketChannel。

最终完成 NioServerSocketChannel 与 NioSocketChannel 的初始化与事件绑定。

关于 NioSocketChannel 详细的初始化流程蕴含在 ChannelInitializer,其机制已经在 手把手教你如何编写一个NIO客户端 中详细介绍。

2.2 NIO绑定机制

在通道完成初始化与注册后,服务端需要进行端口绑定,由 AbstractBootstrap 的 doBind0 方法实现。

在这里插入图片描述

bind 的核心实现最终是调用 Channel 的 bind 方法,最终由 AbstractChannel 类实现:

在这里插入图片描述

bind事件将传播,根据Netty事件传播机制,bind 属于 ChannelOutbound事件,最终将调用 HeadContext的bind方法,最终将调用Unsafe的bind方法,更加具体是调用 AbstractChannel的内部类AbstractUnsafe的bind方法,其代码如下所示:

在这里插入图片描述

doBind 方法是一个抽象方法,NIO服务端的实现:NioServerSocketChannel。

在这里插入图片描述

即最终通过调用NIO底层NioServerSocketChannel 的 bind 方法完成服务端通道的绑定操作,即实现服务端在特定端口监听客户客户端的连接请求。

行文至此开头部门提出的问题大家都能解答了不,为了倒逼读者朋友门真正能理解开头部分的问题,建议读者进行总结,真正做到带着问题阅读源码,当然可以加笔者私信:dingwpmz,共同交流探讨。


欢迎加笔者微信号(dingwpmz),拉您如技术交流加群探讨,关注『中间件兴趣圈』回复**【PDF】**可获取海量学习资料。
在这里插入图片描述

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

无论是哪家公司,都很重视基础,大厂更加重视技术的深度和广度,面试是一个双向选择的过程,不要抱着畏惧的心态去面试,不利于自己的发挥。同时看中的应该不止薪资,还要看你是不是真的喜欢这家公司,是不是能真的得到锻炼。

针对以上面试技术点,我在这里也做一些分享,希望能更好的帮助到大家。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

g-E3L51L9A-1712803363480)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-ILxj333X-1712803363481)]

  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值