在断网的时候,websocket 一直在CLOSING 状态

现象

websocket 先连接成功,然后断网。

由于维护了一套心跳机制,前端发起心跳,如果一段时间内没有收到服务端返回的心跳。则表示连接断开。

用心跳的方式处理断网的兜底情况。

然而,此时网络是断开的,在代码中直接调用websocket.close() 方法,会发现,websocket.readyState 会一直在 WebSocket.CLOSING 状态,等很久也不会触发onclose 回调。

只有网络通的时候才会触发 websocket onclose。

这样会触发不了我的重连逻辑。因为重连逻辑做在onclose 回调里面。

解决

通过定时器检查websocket 的状态,如果在几秒钟之后,还是 CLOSING 状态,则直接调用onclose 的回调。

onclose 的回调有一个参数,可以通过 new CloseEvent 来模拟,代码如下。

javascript 复制代码
const ws = new WebSocket('ws://xxxx');

ws.onclose = onclose;

function onclose(e){}


// 可以在检测到closing 状态超时了后,主动调用onclose 回调,自行模拟event

onclose(new CloseEvent('close', {
    wasClean: false,
    code: 3000,
    reason: 'websocket closing timeout',
}))

还要注意的是,在重新new Websocket 之前,要清除当前的websocket实例,其中的各种回调要置为null (onopen, onclose, onerror, onmessage)

因为等到重连的时候,这个CLOSING 状态的ws实例会触发onclose,导致onclose回调中的内容被重复执行。

参考

相关推荐
iナナ3 小时前
传输层协议——UDP和TCP
网络·网络协议·tcp/ip·udp
舒一笑4 小时前
Mac 上安装并使用 frpc(FRP 内网穿透客户端)指南
后端·网络协议·程序员
华强笔记4 小时前
Linux内存管理系统性总结
linux·运维·网络
iY_n6 小时前
Linux网络基础
linux·网络·arm开发
EggrollOrz6 小时前
网络编程day3
网络
想睡hhh7 小时前
网络基础——Socket编程预备
网络
zzc9217 小时前
Wireshark获取数据传输的码元速率
网络·测试工具·wifi·wireshark·路由器·802.11n·物理层参数
搬码临时工7 小时前
端口映射原理操作详解教程:实现外网访问内网服务,本地路由器端口映射公网ip和软件端口映射域名2种方法
网络·tcp/ip·智能路由器
当你需要个夏天2177 小时前
软考网工选择题-1
网络·智能路由器·选择题·软考网工
极客范儿7 小时前
新华三H3CNE网络工程师认证—等价路由
网络·智能路由器