问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

netty系列之:channel和channelGroup

发布网友 发布时间:2022-09-07 06:09

我来回答

1个回答

热心网友 时间:2024-02-18 00:12

channel是netty中数据传输和数据处理的渠道,也是netty程序中不可或缺的一环。在netty中channel是一个接口,针对不同的数据类型或者协议channel会有具体的不同实现。

虽然channel很重要,但是在代码中确实很神秘,基本上我们很少能够看到直接使用channel的情况,那么事实真的如此吗?和channel相关的ChannelGroup又有什么作用呢?一起来看看吧。

其实netty的代码是有固定的模板的,首先根据是server端还是client端,然后创建对应的Bootstrap和ServerBootstrap。然后给这个Bootstrap配置对应的group方法。然后为Bootstrap配置channel和handler,最后启动Bootstrap即可。

这样一个标准的netty程序就完成了。你需要做的就是为其挑选合适的group、channel和handler。

我们先看一个最简单的NioServerSocketChannel的情况:

这里,我们将NioServerSocketChannel设置为ServerBootstrap的channel。

这样就完了吗?channel到底是在哪里用到的呢?

别急,我们仔细看一下try block中的最后一句:

b.bind(PORT).sync()实际上返回了一个ChannelFuture对象,通过调用它的channel方法,就返回了和它关联的Channel对象。

然后我们调用了channel.closeFuture()方法。closeFuture方法会返回一个ChannelFuture对象,这个对象将会在channel关闭的时候收到通知。

而sync方法会实现同步阻塞,一直等到channel关闭为止,从而进行后续的eventGroup的shutdown操作。

在ServerBootstrap中构建模板中,channel其实有两个作用,第一个作用是指定ServerBootstrap的channel,第二个作用就是通过channel获取到channel关闭的事件,最终关闭整个netty程序。

虽然我们基本上看不到channel的直接方法调用,但是channel毋庸置疑,它就是netty的灵魂。

接下来我们再看一下具体消息处理的handler的基本操作:

通常如果需要在handler中向channel写入数据,我们调用的是ChannelHandlerContext的write方法。这个方法和channel有什么关系呢?

首先write方法是ChannelOutboundInvoker接口中的方法,而ChannelHandlerContext和Channel都继承了ChannelOutboundInvoker接口,也就是说,ChannelHandlerContext和Channel都有write方法:

因为这里我们使用的是NioServerSocketChannel,所以我们来具体看一下NioServerSocketChannel中write的实现。

经过检查代码我们会发现NioServerSocketChannel继承自AbstractNioMessageChannel,AbstractNioMessageChannel继承自AbstractNioChannel,AbstractNioChannel继承自AbstractChannel,而这个write方法就是AbstractChannel中实现的:

Channel的write方法,实际上调用了pipeline的write方法。下面是pipeLine中的write方法:

这里的tail是一个AbstractChannelHandlerContext对象。

这样我们就得出了这样的结论:channel中的write方法最终实际上调用的是ChannelHandlerContext中的write方法。

所以上面的:

实际上可以直接从channel中调用:

channel是netty的灵魂,对于Bootstrap来说,要获取到对应的channel,可以通过调用:

来得到,从上面代码中我们也可以看到一个Bootstrap只会对应一个channel。

我们再来看一下channelGroup的定义:

可以看到ChannelGroup实际上是Channel的集合。ChannelGroup用来将类似的Channel构建成集合,从而可以对多个channel进行统一的管理。

可以能有小伙伴要问了,一个Bootstrap不是只对应一个channel吗?那么哪里来的channel的集合?

事实上,在一些复杂的程序中,我们可能启动多个Bootstrap来处理不同的业务,所以相应的就会有多个channel。

如果创建的channel过多,并且这些channel又是很同质化的时候,就有需求对这些channel进行统一管理。这时候就需要用到channelGroup了。

先看下channelGroup的基本使用,首先是创建一个channelGroup:

有了channelGroup之后,可以调用add方法,向其中添加不同的channel:

并且还可以统一向这些channel中发送消息:

基本上channelGroup提供了write,flush,flushAndWrite,writeAndFlush,disconnect,close,newCloseFuture等功能,用于对集合中的channel进行统一管理。

如果你有多个channel,那么可以考虑使用channelGroup。

另外channelGroup还有一些特性,我们来详细了解一下。

ChannelGroup是一个channel的集合,当然我们只希望保存open状态的channel,如果是close状态的channel,还要手动从ChannelGroup中移出的话实在是太麻烦了。

所以在ChannelGroup中,如果一个channel被关闭了,那么它会自动从ChannelGroup中移出,这个功能是怎么实现的呢?

先来看下channelGroup的add方法:

可以看到,在add方法中,为channel区分了是server channel还是非server channel。然后根据channel id将其存入ConcurrentMap中。

如果添加成功,则给channel添加了一个closeFuture的回调。当channel被关闭的时候,会去调用这个remover方法:

remover方法会将channel从serverChannels或者nonServerChannels中移出。从而保证ChannelGroup中只保存open状态的channel。

虽然 ServerBootstrap的bind方法只会返回一个channel,但是对于server来说,可以有多个worker EventLoopGroup,所以当客户端和服务器端建立连接之后建立的accepted Channel是server channel的子channel。

也就是说一个服务器端有一个server channel和多个accepted channel。

那么如果我们想要同时关闭这些channel的话, 就可以使用ChannelGroup的close方法。

因为如果Server channel和非Server channel在同一个ChannelGroup的话,所有的IO命令都会先发给server channel,然后才会发给非server channel。

所以我们可以将Server channel和非Server channel统统加入同一个ChannelGroup中,在程序的最后,统一调用ChannelGroup的close方法,从而达到该目的:

另外,和channel一样,channelGroup的操作都是异步的,它会返回一个ChannelGroupFuture对象。

我们看下ChannelGroupFuture的定义:

可以看到ChannelGroupFuture是一个Future,同时它也是一个ChannelFuture的遍历器,可以遍历ChannelGroup中所有channel返回的ChannelFuture。

同时ChannelGroupFuture提供了isSuccess,isPartialSuccess,isPartialFailure等方法判断命令是否部分成功。

ChannelGroupFuture还提供了addListener方法用来监听具体的事件。

channel是netty的核心,当我们有多个channel不便进行管理的时候,就可以使用channelGroup进行统一管理。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
弱弱的问一句R9 270X显卡怎么样~ 能带得起我的AMD 240CPU么?_百度知 ... i54570cpu华硕z87a主板要配多少的内存条和显卡 i5 3570k配R9 270X显卡,用什么主板和电源? 很容易上火是什么原因 口干舌燥五心烦热失眠多梦夜不能寐请问是什么原因,吃什么能有效... 想问看大家对老妻少夫的问题有何看法? ...战记第十三章第6关打法 山海战记13-6攻略-手游攻略-游戏鸟手游网 ...战记第十七章第1关打法 山海战记17-1攻略-手游攻略-游戏鸟手游网 ...山海战记9-6图文攻略-手游攻略-游戏鸟手游网 ...战记第十二章第2关打法 山海战记12-2攻略-手游攻略-游戏鸟手游网 关于杭州西湖夜景的诗句(描写西湖夜景的诗句有哪些) 苹果笔记本的无线鼠标怎么更换电池 汉朝公主见皇帝时的礼仪视频,知道可以发个链接给我,或者告诉我什么电视... 汉朝的君臣礼仪有哪些? 汉朝男子礼仪 要给iPhone6S PLUPLUS快充必须用ipiPad的充电器吗? 用ipad2充电器可以给苹果6splus充电吗 6splus可以用ipad的充电头吗 祭扫给他呢 保养皮肤有啥好方法? 中学生暑假当家日记 老婆对老公冷淡是怎么回事 海尔滚筒洗衣机 水晶系列的XQG70-B1226A这个咋样,有什么功能? 巴彦县焦氏医药商店怎么样? 小区后面是国家粮库 每天白天不见人 晚上就一直嗡嗡响声音特别大 一整... 难以建立起亲密关系的原因 鄂尔多斯市双源科技有限公司怎么样? 南梨园粮库再那啊 鄂尔多斯现代泌尿专科医院附近都有些什么小区? 旅游安全的旅游安全的表现形态 怎样解封? 描写哭声的句子 封禁了怎么解除 初中英语课文如何背诵记忆 骨折后手腕部和手指不灵活 三轮摩托车火花塞不装能蹬动.装上就蹬不动什么原因? 关于吃的文化的诗句 关于饮食的诗句有哪些 关于健康饮食的古文诗句 手机号是, 手机停机了微信帐号还可以用不, 功能会不会受影响! 关于江南饮食的诗句(形容江南美景美人美食的诗句) 快速提升学习的方法 60种快速提升自己能量的好方法 IAM即热饮水机的功率很高吗?不然为啥烧水这么快? 深圳楼市低迷,多家中介门店关门,为何目前购房者相对谨慎? 深圳某类房子突然卖爆,价格飙涨50%!消费者追高买房有何风险? ...购房价是100多万,合同写的是30多万,是否有风险? 在深圳,手头有三十几万闲钱,买不了房,各位条友给点投资建议? 鄂g妆网备字什么意思 有个朋友说这个叫花叶万年青,但我看了一下,它和花叶万年青有点不同...