正确理解IM长连接的心跳及重连机制,并动手实现(有完整IM源码)即时通讯开发

什么场景下需要心跳呢?目前我们接触到的大多是一些基于长连接的应用需要心跳来“保活”。

由于在长连接的场景下,客户端和服务端并不是一直处于通信状态,如果双方长期没有沟通则双方都不清楚对方目前的状态,所以需要发送一段很小的报文告诉对方“我还活着”。

同时还有另外几个目的:

本文配套的CIM源码地址:

阅读本文需要一定的网络编程以及Netty方面的知识。

有关网络编程基础知识,请阅读以下资料:

有关Netty框架方面的知识,请阅读以下资料:

学习交流:

心跳其实有两种实现方式:

2)应用层自己实现。

所以我们这里所讨论的都是应用层的实现:

常规的实现应当是:

1)开启一个定时任务,定期发送心跳包;

4)超过后则认为服务端出现故障,需要重连。

这样确实也能实现心跳,但并不友好。

在正常的客户端和服务端通信的情况下,定时任务依然会发送心跳包;这样就显得没有意义,有些多余。所以理想的情况应当是客户端收到的写消息空闲时才发送这个心跳包去确认服务端是否健在。

来看看cim中的实现:

在pipeline中加入了一个10秒没有收到写消息的IdleStateHandler,到时他会回调ChannelInboundHandler中的userEventTriggered方法。

所以一旦写超时就立马向服务端发送一个心跳(做的更完善应当在心跳发送失败后有一定的重试次数)。

这样也就只有在空闲时候才会发送心跳包。但一旦间隔许久没有收到服务端响应进行重连的逻辑应当写在哪里呢?

先来看这个示例:

超过则重连。

也就是heartBeatHandler.process(ctx);的执行逻辑。

伪代码如下:

longheartBeatTime=appConfiguration.getHeartBeatTime()*1000;

LonglastReadTime=NettyAttrUtil.getReaderTime(ctx.channel());longnow=System.currentTimeMillis();if(lastReadTime!=null&&now-lastReadTime>heartBeatTime){reconnect();}}

我们假设下面的场景:

2)这时服务端突入出现down机,那么理想情况下应当是客户端迟迟没有收到服务端的响应从而userEventTriggered执行定时任务;

但却事与愿违,并不会执行2、3两步。

因为一旦服务端down机、或者是与客户端的网络断开则会回调客户端的channelInactive事件。

\

这里的destroy()方法会把之前开启的定时任务都给取消掉。所以就不会再有任何的定时任务执行了,也就不会有机会执行这个重连业务。

因此我们得有一个单独的线程来判断是否需要重连,不依赖于IdleStateHandler。

于是cim在客户端感知到网络断开时就会开启一个定时任务:

之所以不在客户端启动就开启,是为了节省一点线程消耗。网络问题虽然不可避免,但在需要的时候开启更能节省资源。

在这个任务重其实就是执行了重连,限于篇幅具体代码就不贴了,感兴趣的可以自行查阅。

同时来验证一下效果:

启动两个服务端,再启动客户端连接上一台并保持长连接。这时突然手动关闭一台服务,客户端可以自动重连到可用的那台服务节点。

启动客户端后服务端也能收到正常的ping消息:

利用:info命令查看当前客户端的链接状态发现连的是9000端口。

:info是一个新增命令,可以查看一些客户端信息。

这时我关掉连接上的这台节点:

这时客户端会自动重连到可用的那台节点。这个节点也收到了上线日志以及心跳包。

现在来看看服务端,它要实现的效果就是延迟N秒没有收到客户端的ping包则认为客户端下线了,在cim的场景下就需要把他踢掉置于离线状态。

有关消息发送误区:

这里依然有一个误区,在调用ctx.writeAndFlush()发送消息获取回调时。

其中是isSuccess并不能作为消息发送成功与否的标准:

也就是说即便是客户端直接断网,服务端这里发送消息后拿到的success依旧是true。这是因为这里的success只是告知我们消息写入了TCP缓冲区成功了而已。

和我之前有着一样错误理解的不在少数,这是Netty官方给的回复:

于是来做个试验:正常通信的客户端和服务端,当我把客户端直接断网时,服务端会自动剔除客户端。

这样就实现了文初的两个要求:

1)服务端检测到某个客户端迟迟没有心跳过来可以主动关闭通道,让它下线;

2)客户端检测到某个服务端迟迟没有响应心跳也能重连获取一个新的连接。

同时也踩了两个误区,坑一个人踩就可以了,希望看过本文的都有所收获避免踩坑。

THE END
1.IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列2)另一种称为延迟消息:即消息从某端发出后,首先进入一个容器进行临时存储,当达到某种条件后,再由这个容器发送给另一端。 在上述“消息传递方式2)”中所指的这个容器的一种具体实现就是MQ消息队列服务。 MQ消息队列中间件是中大型分布式系统中重要的组件,它主要用来解决:应用解耦、异步消息、流量削锋等问题,用以https://cloud.tencent.com/developer/article/1346912
2.QQ里发送文件和发送离线文件有什么不同?发离线文件,文件可以保留7天,好友不在线或关闭窗口,好友下次登陆,还能收到的。操作方法如下: 1、首先打开电脑上的QQ软件登陆,点击要发送文件的好友,发现好友是不在线的。 2、打开好友聊天窗口后点击发送文件。 3、弹出的界面点发送离线文件。 4、然后选择电脑上要发送的文件,这样文件就离线发送给了好友。 5、当https://wenda.so.com/q/1455960290721244
3.聊天在线与离线传输文件qq转离线发送和转在线发送有区别吗微信只支持一种文件发送方式,就是发送方把文件发到文件存储服务,然后接收方从文件服务器进行下载。然而,在古老的QQ软件,是支持在线传输和离线传输(微信模式)。 1.离线传输 称之为离线传输,其实是相对与在线传输而言。在qq的概念里,离线传输就是及时对方不在线,仍然可以向其发送文件。 https://blog.csdn.net/littleschemer/article/details/144161451
4.邮件基本概念及发送方式蚂蚁小哥邮件基本概念及发送方式 回到目录 ↑↑↑ 一:邮件发送的基本介绍 在工作中我相信大家会经常和邮件打交道,用邮件来进行信息的交流和汇报工作情况;但是在我们程序员眼里,邮件的用处还是挺广泛的,比如我们在注册账号完成时平台会发送一封邮件给我们,让我们点击邮件里的链接来激活当前注册的账号;其实邮件还可以实现验证码https://www.cnblogs.com/antLaddie/p/15546365.html
5.在线传送和离线传送有什么区别在线传送和离线传送有..但对于大型软件或大量的多媒体文件来说选择哪种方式就要根据具体情况而定:是否需要在两台机器间建立即时连接以及是否能接受较长的传送延迟都可能影响最终的选择https://tieba.baidu.com/p/8808758805
6.交易公告3.11、冷却方式:ONAN(油浸空气循环自冷式) 3.12、有载调压分接开关:变压器生产厂家配套提供,要求选择国内名牌产品,满足国家及行业相关标准,同时必须满足当地海拔 3300m 及其他相关环境参数的要求。 3.13、其他诸如轨距、变压器套管外绝缘泄漏比距、绕组绝缘耐热等级、绕组绝缘水平、温升限值、电压升高时的运行持续时间等https://www.qhggzyjy.gov.cn/ggzy/jyxx/001001/001001003/20211224/4629299d-f91b-4656-be33-3d3213b51cd3.html
7.奥鹏作业答案优学网A、收/发双方可以使用各自独立的接收器/发送器时钟 B、收发双方不必同步 C、省去了同步字符所以传送效率高 D、校验方法多 三、判断题(共5题,20分) 1.传输距离较远时,常采用并行传送方式,传输距离较近时,常采用串行传送方式。 A、错误 B、正确 http://www.youxue100f.com/jldx/2023-04-24-11965.html
8.前端和框架(144)少部分浏览器不支持,浏览器支持的程度与方式有区别。 http://www.cnblogs.com/best/p/5695570.html#_label1 3、什么是magic string 4、如何创建响应式布局 @media (min-width: 768px){ .pg-header{ background-color: green; } } @media (min-width: 992px){ https://www.jianshu.com/p/057e028aa44f
9.qq离线文件如何接收怎样发送qq离线文件3、选择要发送的文件,点击确定,文件开始传送。 4、传送完成之后,聊天窗口提示离线文件上传成功,此时作为接收方也会收到提示。 QQ离线文件和在线文件有什么区别 1、文件处理方式不同 在线传送:文件是点对点的,就是文件的发收双方。 离线传送:发送方先将文件上传至服务器,待接收方上线后会收到文件接收通知,直接从服https://www.tianqi.com/toutiao/read/103521.html
10.即时通信教学设计9篇(全文)(1) 图七所示的就是封锁UDP方式之后的抓包图, 由于Binding Response包被拦截, 客户端发送Binding Request之后长时间没有收到来自服务器发送回来的Binding Response包, 客户端就会自动转向使用TCP (9000) 端口和HTTP (80) 端口来传输数据。 (2) 图八黑色的包就是MSN在视频传输时通过TCP直接传输时被截住的包。 https://www.99xueshu.com/w/file7y9jjdrh.html
11.思科网络技术学院教程(第6版):网络简介第8章“对IP网络划分子网”:探讨如何根据网络需求以最佳的方式划分IP地址空间,以改善网络性能。探讨如何确定有效的主机地址以及子网地址和广播地址。这一章探讨子网划分时,涉及IPv4和IPv6。 第9章“传输层”:介绍了传输控制协议(TCP)和用户数据报协议(UDP)以及它们如何通过网络传输信息。探讨TCP如何使用分段、三次握手https://www.epubit.com/bookDetails?id=N15003
12.我们给区块链提了这100个问题来全面扫盲科技频道区块链是一个集合了密码学、分布式储存、智能合约、共识算法等多种新兴技术的数据传输方式,本质上是一种集成技术,而非一个特定技术的发明。 区块链本质上是一个应用了密码学技术的,多方参与、共同维护、持续增长且不可篡改的分布式数据库系统,也称为分布式共享账本。在数据上传的过程中,数据会被打包到一起形成一个https://tech.hexun.com/2019-11-13/199255086.html
13.网红面试题:从输入Url到看到页面发生了什么主要是为了确认双方的接收能力和发送能力是否正常、制定自己的初始化序列号为后面的可靠性传送做准备。 可以理解为一对男女要分手。 女方提出分手,说你对我不好,我要分手。 男方觉得需求合理,同意分手,但分手之前要把联系方式、合照、各种乱七八糟的的事情算清楚再分手。 https://www.51cto.com/article/707647.html
14.揭秘QQ文件传输,是否全经服务器转发及传输速度解析2、在局域网内,QQ传输文件通常不会经过腾讯的服务器,而是通过点对点的方式进行传输,这样可以提高传输速度。 QQ在线发送和离线发送的区别 1、在线发送文件需要双方同时在线,而离线发送文件则不需要接收方在线,离线发送时,发送方只需将文件上传至服务器,接收方上线后会收到文件接收通知,然后从服务器下载文件。 http://www.cloud12.cn/53B2f5776b6a.html
15.面试:可以写到简历上的分布式IM即时通讯系统冰河技术分布式IM即时通讯系统本质上就是对线上聊天和用户的管理,针对聊天本身来说,最核心的需求就是:发送文字、图片、文件、语音、视频、消息缓存、消息存储、消息未读、已读、撤回,离线消息、历史消息、单聊、群聊,多端同步,以及其他一些需求。 对用户管理来说,存在的需求包含:添加好友、查看还有列表、删除好友、查看好友https://binghe.gitcode.host/md/project/im/start/2023-12-08-interview.html
16.一种LORA集中器及其数据传输方法系统专利专利查询LORA节点处于离线状态,则LORA集中器返回给服务器错误代码,LORA节点处于在线状态,LORA集中器将服务器发送的参数配置命令进行存储,并向服务器发送等待指令,当LORA节点上传数据完成后,LORA集中器再将服务器发送的参数配置命令发送至LORA节点,如果节点类型为实时传输类型,则服务器发送的参数配置命令立即通过LORA集中器发送至https://www.tianyancha.com/patent/6f9b691ec582185f824a2543929706f8