中年|Web端即时通讯实践干货:如何让WebSocket断网重连更快速?( 二 )
4、WebSocket重连过程拆解首先考虑一个问题 , 何时需要重连?
最容易想到的是WebSocket连接断了 , 为了接下来能收发消息 , 我们需要再发起一次连接 。
但在很多场景下 , 即便WebSocket连接没有断开 , 实际上也不可用了 。
比如以下场景:
1)设备切换网络;
2)链路中间路由崩溃(常识是一条socket连接对应的网络通路上 , 会存在很多路由设备);
3)链路的前端出口不可用(比如家庭WiFi中 , 网络连接正常 , 但实际运营商的宽带已经欠费被停机);
4)服务器负载持续过高无法响应等 。
这些场景下的WebSocket都没有断开 , 但对上层来说 , 都没办法正常的收发数据了 。
因此在重连前 , 我们需要一种机制来感知连接是否可用、服务是否可用 , 而且要能快速感知 , 以便能够快速从不可用状态中恢复 。
一旦感知到了连接不可用 , 那便可以弃旧图新了 , 弃用并断开旧连接 , 然后发起一次新连接 。 这两个步骤看似简单 , 但若想达到快 , 且不是那么容易的 。
首先:是断开旧连接 , 对客户端来说 , 如何快速断开?协议规定客户端必须要和服务器协商后才能断开WebSocket连接 , 但是当客户端已经联系不上服务器、无法协商时 , 如何断开并快速恢复?
其次:是快速发起新连接 。 此快非彼快 , 这里的快并非是立即发起连接 , 立即发起连接会对服务器带来不可预估的影响 。 重连时通常会采用一些退避算法 , 延迟一段时间后再发起重连 。 但如何在重连间隔和性能消耗间做出权衡?如何在“恰当的时间点”快速发起连接?
带着这些疑问 , 我们来细看下这三个过程:
本文插图
5、快速重连关键1:快速感知何时需要重连5.1 场景
需要重连的场景可以细分为三种:
1)连接明确断开了;
2)连接没断但是不可用了;
3)连接对端的服务不可用了 。
对于第一种场景:这很简单 , 连接直接断开了 , 肯定需要重连了 。
对于后两者:无论是连接不可用 , 还是服务不可用 , 对上层应用的影响都是不能再收发即时消息了 。
5.2 心跳包主动探测网络可用性
所以从上面这个角度出发 , 感知何时需要重连的一种简单粗暴的方法就是通过心跳包超时:发送一个心跳包 , 如果超过特定的时间后还没有收到服务器回包 , 则认为服务不可用 , 如下图中左侧的方案(这种方法最直接) 。
本文插图
那如果想要快速感知呢 , 就只能多发心跳包 , 加快心跳频率 。 但是心跳太快对移动端流量、电量的消耗又会太多 , 所以使用这种方法没办法做到快速感知 , 可以作为检测连接和服务可用的兜底机制 。
5.3 被动监听网络状态改变
如果要检测连接不可用 , 除了用心跳检测 , 还可以通过判断网络状态来实现 , 因为断网、切换wifi、切换网络是导致连接不可用的最直接原因 , 所以在网络状态由offline变为online时 , 大多数情况下需要重连下 , 但也不一定 , 因为webscoket底层是基于TCP的 , TCP连接不能敏锐的感知到应用层的网络变化 , 所以有时候即便网络断开了一小会 , 对WebSocket连接是不会有影响的 , 网络恢复后 , 仍然能够正常地进行通信 。
因此在网络由断开到连接上时 , 立即判断下连接是否可用 , 可以通过发一个心跳包判断 , 如果能够正常收到服务器的心跳回包 , 则说明连接仍是可用的 , 如果等待超时后仍没有收到心跳回包 , 则需要重连 , 如上图中的右侧 。 这种方法的优点是速度快 , 在网络恢复后能够第一时间感知连接是否可用 , 不可用的话可以快速执行恢复 , 但它只能覆盖应用层网络变化导致WebSocket不可用的情况 。
推荐阅读
- 中年|北斗“一张网”可实现全天候、高精度、自主可控服务
- 中年|Python编程语言有什么独特的优势呢?
- 中年|谈一谈我的十年机械工作经历
- 中年|弹无虚发的背后,国产弹药质量把关人,精密机床都要自叹不如
- 中年|宿迁深圳招商再结硕果,签约项目19个,协议总投资158亿元
- 中年|苹果:已终止Epic Games开发者账号
- 中年|圆满的结局!苹果微信之间不用再二选一,美国政府还是做出让步
- 中年|国家能源集团成功研发矿用卡车能耗制动开关预警装置
- 中年|什么是余压监控系统?余压监控系统如何接线和安装?一篇文章搞懂
- 中年|上线供应链金融、搭建标准质量体系,三全产业伙伴卓越质量联盟正式启动