正确理解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.QQ在线传文件,高效便捷的文件传输新选择电源摘要:QQ在线传文件是一种高效便捷的文件传输方式。用户可以通过QQ聊天窗口直接发送和接收文件,实现快速的文件传输。这种方式不仅简单易用,而且传输速度较快,广泛应用于个人、企业和组织之间的文件共享和交换。QQ在线传文件已成为现代通讯中不可或缺的一部分。 http://m.zj-xy.net/post/21455.html
2.QQ中的4G在线标志,技术原理与含义解析五金交电在QQ中,用户的网络状态标识是判断其是否在线以及当前网络状况的重要依据,这些状态标识包括“在线”、“离线”、“忙碌”、“隐身”等。“在线”表示用户当前正在使用QQ,且网络连接正常;“离线”则表示用户当前未登录或网络断开,而“忙碌”和“隐身”则是用户根据自己的需求设置的特殊状态,近年来,随着智能手机的普及和http://xjxygt.cn/post/15467.html
3.IM小程序能否支持离线消息功能?离线消息的存储和同步需要高效的数据处理能力,如何在有限的资源下优化性能,是一个技术难题。 五、实现离线消息功能的几种方案 1. 基于服务器端存储的方案 原理:服务器端维护一个离线消息队列,当用户离线时,将发送给该用户的消息存入队列;用户上线后,从队列中取出消息并推送。 https://www.huanxin.com/news/13323
4.离线发送文件和在线发送文件有区别吗?在线发送文件与离线发送文件的区别是:一、所指对象不一样 平时所说的在线发送文件必须要接收双方同时在线,就相当于你在玩电脑,另外一方也得在玩电脑或者手机,这样才可以在线发送;而离线发送文件是不需要接收方同时在线的。二、时间不一样 在线发送文件必须要接收双方同时在场,离线发送文件是可以在接收https://zhidao.baidu.com/question/699573959094688004.html
5.在线发送和离线发送的区别爱问知识人区别:在线发送需要双方都在线,离线发送不需要接收方在线,对方离线或者隐身也可以发送;在线发送需要及时https://iask.sina.com.cn/b/new2I0a4geK5Qx.html
6.qq离线文件如何接收怎样发送qq离线文件2、在弹出来的下拉窗口选择“发送离线文件” 3、选择要发送的文件,点击确定,文件开始传送。 4、传送完成之后,聊天窗口提示离线文件上传成功,此时作为接收方也会收到提示。 QQ离线文件和在线文件有什么区别 1、文件处理方式不同 在线传送:文件是点对点的,就是文件的发收双方。 https://www.tianqi.com/toutiao/read/103521.html
7.qq离线qq离线和离线请留言有什么区别离线和离线请留言有什么区别呢?主要有以下几点区别。 离线是指我们的QQ账号处于离线状态,我们无法接收到其他人发送的消息,而离线请留言是指我们给对方发送消息时,对方不在线,我们选择将消息保存在对方的聊天记录中,等到对方上线后才能看到,可以说,离线请留言是一种主动行为,而离线则是一种被动状态。 http://www.m.0632fc.cn/news/29442.html
8.常见问题和群组有什么区别? 一个聊天室支持100万人。聊天室和群组最大的区别在于,聊天室的消息没有推送通知和离线保存,也没有常驻成员的概念,只要进入聊天室即可接收消息,开始聊天, 一旦退出聊天室,不再会接收到任何消息、通知和提醒。注意:进入聊天室会自动获取最近50条消息,客户端目前不支持创建聊天室 实时音视频怎么收费?https://docs.jiguang.cn/jmessage/guideline/faq
9.第五次全国经济普查专项试点数据处理问题解答(一)3.清查调查员和普查调查员账号注册有何要求? 答:清查调查员注册的手机号码须在单位清查平台的调查员管理功能中提前预置。普查调查员注册的手机号码需要在普查登记数据处理平台提前预置,否则无法进行验证码的发送。 4.普查阶段对自主填报的用户有什么要求? https://www.yueyang.gov.cn/tjj/22746/22753/67182/67186/content_2080266.html
10.理解iOS消息推送一文就够:史上最全iOSPush技术详解4)UNPushNotificationTrigger 表示通知是从Apple推送通知服务发送的对象。 如果以时间间隔(TimeInterval)来触发,则设置触发器代码为: 推送本地push的代码为: 5、在线、离线(远程)push流程 5.1 在线push流程 在线push相对简单,由于是内部实现,具体流程如上面所示。 https://www.songma.com/news/txtlist_i2865v.html
11.聊天在线与离线传输文件qq转离线发送和转在线发送有区别吗微信只支持一种文件发送方式,就是发送方把文件发到文件存储服务,然后接收方从文件服务器进行下载。然而,在古老的QQ软件,是支持在线传输和离线传输(微信模式)。 1.离线传输 称之为离线传输,其实是相对与在线传输而言。在qq的概念里,离线传输就是及时对方不在线,仍然可以向其发送文件。 https://blog.csdn.net/littleschemer/article/details/144161451
12.什么是QQ离线文件什么是QQ在线文件腾讯微信最近不少人有点迷糊这类问答,其实离线文件和在线文件的区别是在线发送文件是点对点的,就是文件的发收双方。离线文件是发送方先将文件上传至服务器,待接收方上线后会收到文件接收通知,直接从服务器进行下载。 什么是QQ离线文件: 1、离线文件是发送方先将文件上传至服务器;http://www.puhuahui.com/4363.html
13.qq离线是退出账号了吗?离线和退出有什么区别 离线和退出在功能上有一些差别。当你选择退出QQ时,你的账号会完全退出,无法接收和发送消息。而选择离线则不同,你的账号依然登录,只是临时关闭了消息接收功能。 当你处于离线状态时,其他好友并不能把你从他们的好友列表中删除,因为虽然你不在线,但你的状态仍然是存在的。 https://www.xiedaoicec.com/2e419613ecf8b26e.html
14.qq离线请留言什么意思(qq显示的离线请留言和离线有什么区别)今天来给大家分享一下关于qq离线请留言什么意思的问题,以下是对此问题的归纳整理,让我们一起来看看吧。 qq离线请留言什么意思 qq离线请留言的意思是好友不在线,但是已经设置接收离线消息了,即使不在线也可以收到;但不超过24小时没有登录QQ。QQ离线的意思是好友不在线,且超过24小时没有登录QQ。 http://www.wengnai.com/html/706009.html
15.千牛挂起和离线的区别,淘宝客服挂起有影响吗?千牛离线:千牛离线状态则表示客服不在线或者不可接受用户消息。在这种状态下,用户发送的消息将无法直接送达客服,需要等待客服上线后才能收到回复。通常情况下,客服处于离线状态可能是因为暂时离开工作岗位,或者已经下班休息。 总的来说,千牛挂起和离线的区别在于客服是否能够接收用户消息和进行回复,挂起表示客服能够接收消息https://www.kaitao.cn/article/20240402122913.htm
16.王者荣耀里怎么给好友发消息又如何向不在线的好友发送消息王者荣耀通过数年的运行,游戏内容上已经臻至化境,完全可以媲美端游的各项板块,不过新手玩家在进入游戏后,会遇到一系列问题,比如怎么给在线的微信好友发消息,不在线的好友是不是不能发送离线消息,其实这些当然都是可以的! 王者荣耀给好友发消息玩法: 玩家点击进入王者荣耀主页面,直接点击左下方世界聊天频道,里面有喊话功https://www.qqtn.com/article/article_192864_1.html
17.11家最佳电子邮件服务提供商(2022年免费)通过自动操作保护您的帐户,并远离垃圾邮件发送者的异常活动。 它适用于 iOS 和 android 设备,即使离线也能个性化您的体验。 通过添加用户、管理组别名和设置策略,主控制面板可以轻松配置、自定义和调整您的电子邮件内容。 通过右键单击搜索来自任何发件人的电子邮件,并提供 50 多个键盘快捷键。 https://www.douban.com/note/828512166/
18.一文搞懂:Web3.0钱包是什么?如何创建和使用?如何确保安全?硬件钱包是专用的物理设备,设计用于离线存储加密货币私钥。这类钱包提供最高级别的安全性,因为私钥永远不会暴露在联网环境中,防止黑客攻击。 常见的硬件钱包 Ledger:Ledger钱包(如Ledger Nano S和Ledger Nano X)是市场上最受欢迎的硬件钱包之一,支持多种加密货币。它通过USB或蓝牙与计算机或手机连接,提供高度的安全性https://www.528btc.com/zhuanti/1316042.html
19.质检培训完整操作指南针对自定义添加的质检标准,如果是有规律可循的标准,建议选择规则检出,然后把规则配起来,规则支持买家咨询商品/买家咨询时间/买家消息内容/客服消息发送位置/是否下单/客服回复行为/等多条件。 设置自定义规则检出后,满足规则条件的会话会自动打上扣分项或加分项的标签。 https://www.360doc.cn/article/27880450_1075329921.html
20.QQ服务器拒绝发送离线文件的解决方法(对方不在线的情况下)QQ技巧经常会使用QQ来接收和发送文件,如果对方不在线,还可以离线发送文件。但今天遇到了这种情况,发送离线文件时,出现了服务器拒绝了发送请求,这是什么原因,有什么解决方法? 服务器拒绝发送离线文件 服务器拒绝了您发送离线文件的原因: 第一种:传输文件容量超过限制;实际上所有的普通QQ用户都可用使用QQ离线文件功能,只不过https://www.jb51.net/qq/249795.html
21.在Mac上的“邮件”中让电子邮件账户离线或在线让所有账户离线:选取“邮箱”>“让所有账户离线”。 让特定账户离线(如果你有多个账户):选取“邮箱”>“在线状态”>“使[账户]离线”。 “邮件”边栏中账户邮箱旁边和个人收藏栏末尾的闪电图标 表示该账户已离线。 账户离线时,你不能收取或发送邮件,但可以编写邮件以稍后发送。你可以将邮件存储为草稿并于账户再次https://support.apple.com/zh-cn/guide/mail/mlhlp1032/mac