Netty的future.channel.closeFuture.sync;到底有什么用

Netty的future.channel.closeFuture.sync;到底有什么用,第1张

>本文采用 Json数据格式
目前由登录,心跳,数据透传3个接口组成
登录:
'{"companyID":"0","stateCode":"10001"}'
注释:companyID:为身份编号:服务器根据此字段将连接对象分组
            stateCode : *** 作编号,登录固定为10001 
返回数据:
'{"channelNumber":"1""stateCode":"10001","serialNumber":"1234","msg":"登录成功","dataType":"0","data":"XXXX"}'
注释:channelNumber:服务器分配的唯一身份码,断开后即失效
            stateCode: *** 作编号,登录固定为10001 
            serialNumber: *** 作流水号
            msg: *** 作提示
            dataType: 0 没有数据 1 数据是字典类型 2 数据是数组类型
            data:透传数据 格式自定义

心跳:
'{"companyID":"0","channelNumber":"1","stateCode":"10002"}'
注释:  companyID:为身份编号:服务器根据此字段将连接对象分组
           channelNumber:服务器分配的唯一身份码,断开后即失效
           stateCode : *** 作编号,心跳固定为10002
返回数据:
'{"channelNumber":"1""stateCode":"10002","serialNumber":"1234","msg":"登录成功","dataType":"0","data":"XXXX"}'
注释:格式同上 修改对应参数即可

数据透传:
'{"channelNumber":"1","stateCode":"99999","serialNumber":"1234","msg":"数据透传","dataType":"1","data":{}}'
注释:channelNumber:服务器分配的唯一身份码,断开后即失效
           stateCode: *** 作编号,透传时自定义
           serialNumber: *** 作流水号
           msg: *** 作提示
           dataType: 0 没有数据 1 数据是字典类型  2 数据是数组类型
           data:透传数据 格式自定义

透传示例:
'{"channelNumber":"1","stateCode":"99999","serialNumber":"1234","msg":"数据透传","dataType":"1","data":{"msgLevel":"1","msgType":"1","pageNumber":"1","title":"1","content":"1","imgUrl":"1","time":"1"}}'
 注释: msgLevel :1-9 越高越重要
             msgType  : 1 通知类型信息 2 *** 作类型信息 3 预警类型信息 9 透传base64字典数据
             pageNumber : web页面上对应的功能页面编码
             title         : 本次消息的标题
             content   : 本次消息的文本
             imgUrl     : 本次消息的
             time         : 本次消息的时间

上一篇中 netty注册流程分析一 ,分析到了channel注册到nioEventLoop中了,接下来就是doBind0方法

通过channelbind内部最终会掉用pipeline上TailContext的bind方法,这个看下 这篇文章

从方法中可以看出调用bind方法,并不是tail,而是它的上一个出站处理器,也就是HeadContext,HeadContext的bind方法又是调用channel内部unsafe的bind方法。

这个方法又主要有三个步骤,绑定到服务器端口doBind,提交一个触发channelActive的任务到队列中,promise的result设置为成功,通知监听器。

触发channel的channelActive方法,内部会调用HeadContext的channelActive

HeadContext直接转发给下一个inboundHandler的channelActive,再调用readIfIsAutoRead

而看到channelread方法,程序又会执行太Context的read方法,参考 channel、handler调用关系 ,而TailContext最终又是调用channel中Unsafe的beginRead方法

直到这边,netty才将NioServerSocketChannel注册到Selector的监听事件注册为accept。当NioEventLoop执行完队列所有的任务之后,在事件循环开始的地方又进入Selectorselect的阻塞,监听客户端的连接。

最后总结一下,netty直接调用channel的相关方法时,会先转给pipeline,再由pipeline根据入站事件还是出站事件,转给HeadContext和TailContext,而TailContext在处理出站事件时,最终又回到channel的unsafe对象去执行相应的IO方法。

至此,netty只是将channel注册到selector上,且监听accept事件。下篇再来讲述下NioEventLoop的事件循环,及如何将新的连接channel注册到worker group上去监听read事件。

从DDR的访存特性来说,对同一块DDR,两个访存 *** 作之间需要一些时间间隔,这里面包括CL (CAS时延), tRCD(RAS到CAS时延),tRP(预充电有效周期)等。
为了提高DDR的访存速度,可以使用多通道(channel)技术。典型的台式机和笔记本CPU很早就支持双通道,现在还加入了三通道。如果数据分布在插在不同的通道上的内存条上,内存控制器可以不管上面这些延迟啊时序啊,同时读取他们,速度可以翻倍甚至三倍(如果支持的通道数更多,则速度提高的更多)。高通的第一代ARM服务器SoC芯片使用了4个DDR控制器,即支持四通道。
但是由于程序的局限性,一个程序并不会把数据放到各个地方,从而落入另一个DIMM里,往往程序和数据都在一个DIMM里,加上CPU的Cache本身就会把数据帮你预取出来,这个多通道对速度的提高就不那么明显了。
这时就要使用另外一种提高速度的方法了,就是让同一块内存分布到不同的通道中去,这种技术叫做交织,Interleaving 这样无论Cache命中与否都可以同时存取,多通道的技术才能发挥更大的用处。

引用来自“预兆师”的答案
引用来自“石头哥哥”的答案
嗯 channel实际就是一个客户端和server的一个抽象的管道 ,netty封装了网络的底层 所以 你不必太多去掀开一些它封装的东西来处理 对于还不熟悉的开发者来讲的 话;你可以这样处理 在连接上来的时候 你创建一个session会话来持有这个channel ,每一个session有一个ID ,那么 你在业务层就可以通过这个ID拿到session 从而将这个数据发送出去,你这里 其实在服务器端就是sessionA sessionB ,A,B两个客户端连接服务器了 ,那么 就创建sessionA sessionB ,并产生一个ID (ID 保持唯一就可以了),A向B发送,那么实际就是通过服务器来转发A的消息到B,那么你必然拿到B的ID,几在A的消息中发送B的ID,这样就可以拿到sessionB ,然后channelwrite(); 消息的转发 与消息的推送 关键就在与知道sessionID,顺利得到相应的session 这样就可以解决问题了;
创建session的位置在channelActive(ChannelHandlerContext ctx);标记channel的方式很多 ,上面的和你描述的一样 只是 封装了一个session来持有channel罢了;


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13450995.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-08-09
下一篇 2023-08-09

发表评论

登录后才能评论

评论列表(0条)

保存