参考此博客后实践了一下:WebSocket断开原因、心跳机制防止自动断开连接
主要有时收藏的文章可能原文连接失效了,所以自己实践并记录一下,以备来日所需。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div></div>
<script>
/**
* 逻辑概要:
* 1、判断浏览器是否支持WebSocket
* 2、支持的情况下,连接ws,将ws实例对象保存起来
* 3、接收到消息后,执行我们的处理函数,同时加入心跳包机制
* 4、页面离开时断开ws连接
*/
let ws = null; // WebSocket实例对象
let lockReconnect = false;
let wsUrl = "找个WebSocket服务端测试连接地址,百度一下就有";
createWebSocket(wsUrl);
function createWebSocket(url) {
try {
if ('WebSocket' in window) {
console.log('start')
ws = new WebSocket(url);
initEventHandle();
}
} catch (e) {
reconnect(url);
console.log('new出错', e);
}
}
function initEventHandle() {
ws.onclose = function (e) {
console.log('ws连接关闭!' + new Date(), e);
reconnect(wsUrl);
}
ws.onerror = function (e) {
console.log('ws连接错误!', e);
}
ws.onopen = function (e) {
console.log('ws连接成功!' + new Date(), e);
heartCheck.reset().start();
}
ws.onmessage = function (e) {
console.log('ws收到新消息' + new Date(), e)
heartCheck.reset().start();
}
}
function reconnect(url) {
console.log('准备重新连接' + new Date());
if (lockReconnect) return;
lockReconnect = true;
setTimeout(() => {
createWebSocket(url);
lockReconnect = false;
}, 2000)
}
//心跳检测
let heartCheck = {
timeout: 1000*10, //多久间隔发一次心跳
timeoutObj: null,
serverTimeoutObj: null,
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
let self = this;
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
ws.send("ping");
console.log(">>发送心跳ping!" + new Date())
self.serverTimeoutObj = setTimeout(function () { //如果超过一定时间还没重置,说明后端主动断开了
console.log('服务端断开了连接')
ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
}, self.timeout)
}, this.timeout)
}
}
window.onbeforeunload = function () {
console.log('页面离开', new Date())
ws.close();
}
</script>
</body>
</html>