长连接的心跳及重连设计(下)

简介: 什么场景下需要心跳呢? 目前我们接触到的大多是一些基于长连接的应用需要心跳来“保活”。 由于在长连接的场景下,客户端和服务端并不是一直处于通信状态,如果双方长期没有沟通则双方都不清楚对方目前的状态;所以需要发送一段很小的报文告诉对方“我还活着”。 同时还有另外几个目的: 服务端检测到某个客户端迟迟没有心跳过来可以主动关闭通道,让它下线。 客户端检测到某个服务端迟迟没有响应心跳也能重连获取一个新的连接。

靠谱实现


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

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



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



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


同时来验证一下效果。


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



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


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



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


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


kill -9 2142


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


服务端自动剔除离线客户端


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


消息发送误区


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


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



也就是说即便是客户端直接断网,服务端这里发送消息后拿到的 success 依旧是 true


这是因为这里的 success 只是告知我们消息写入了 TCP 缓冲区成功了而已。


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



相关 issue


github.com/netty/netty…


同时感谢 95老徐以及闪电侠的一起排查。


所以我们不能依据此来关闭客户端的连接,而是要像上文一样判断 Channel 上绑定的时间与当前时间只差是否超过了阈值。



以上则是 cim 服务端的实现,逻辑和开头说的一致,也和 Dubbo 的心跳机制有些类似。


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



总结


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


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


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


本文所有相关代码都在此处,感兴趣的可以自行查看:


github.com/crossoverJi…


相关文章
|
3月前
|
前端开发
websocket的心跳机制
websocket的心跳机制
79 2
|
9月前
|
Java Windows
JavaWebSocket心跳机制详解
WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议,它提供了一种简单而强大的方式来实现实时数据传输。在使用WebSocket时,心跳机制是非常关键的,它能够保持连接的稳定性并及时发现连接的异常。本文将详细解释JavaWebSocket心跳机制的实现原理和步骤。
243 0
|
5月前
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的
238 2
|
5月前
|
移动开发 HTML5
WebSocket心跳机制
WebSocket心跳机制
33 0
|
5月前
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的,
MQTT的心跳保活机制是通过`setKeepAliveInterval()`方法设置的,
145 1
|
5月前
MQTT协议本身是支持心跳保活机制的
MQTT协议本身是支持心跳保活机制的
82 3
|
5月前
|
前端开发 Java Spring
WebSocket心跳机制(笔记大全)
WebSocket心跳机制(笔记大全)
421 0
|
6月前
|
tengine 网络协议 Linux
关于长连接服务器和客户端之间要加入心跳的一些讨论
关于长连接服务器和客户端之间要加入心跳的一些讨论
|
7月前
|
网络协议
选择长连接 or 短连接,大量 Timewait 的产生时如何处理?
网络通讯中,常见的两个连接类型分别是长连接和短连接。长连接指在一定时间内保持连接不断开,而短连接则指每次连接只进行一次通信,通信结束后即时断开连接。在实际应用中,不同类型的连接有着不同的应用场景和优缺点,而且在网络通讯中可能会遇到大量 Timewait 的产生,这就需要针对不同情况选择不同的处理方案。
|
9月前
|
Java 开发者
JavaHTTP心跳:服务器与客户端实时连接的实现方式
JavaHTTP心跳:服务器与客户端实时连接的实现方式 在网络通信中,实时连接是一种至关重要的功能。它允许服务器与客户端之间保持持久的通信信道,实现快速、高效的数据传输。对于Java开发者来说,实现服务器与客户端之间的实时连接可以通过JavaHTTP心跳技术来实现。本文将介绍如何利用JavaHTTP心跳来实现服务器与客户端之间的实时连接。
219 0

热门文章

最新文章