window.webSocket = {};
var heartCheck = {
lockReconnect: false, //避免ws重复连接
maxReconnectionDelay: 30 * AP.MINUTE, //最大重连时间
minReconnectionDelay: 10 * AP.SECOND, //最小重连时间
reconnectionDelayGrowFactor: 1.5, //自动重连失败后重连时间倍数增长
connectionTimeout: 10 * AP.SECOND,//重连时间
pongTime: 30 * AP.SECOND, //30秒接收心跳
pingTime: (30 * AP.SECOND / 10) * 8,//30秒向服务器发送心跳
timeoutObj: null,//Ping定时器
serverTimeoutObj: null,//Pong定时器
reset: function () {
// clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
PingStart: function () {
var self = this;
this.timeoutObj = setTimeout(function () {
//这里发送一个心跳,后端收到后,返回一个心跳消息,
//onmessage拿到返回的心跳就说明连接正常
if (WEB_SOCKET != null && WEB_SOCKET.readyState == WebSocket.OPEN) {
WEB_SOCKET.send("PING")
self.PingStart();
}
}, this.pingTime) //10秒发送一次心跳
},
PongStart: function () {
var self = this;
self.serverTimeoutObj = setTimeout(function () { //如果超过一定时间还没重置,说明后端主动断开了
if (WEB_SOCKET != null) {
//console.log("服务器30秒没有响应,关闭连接")
WEB_SOCKET.close();
}
}, self.pongTime)
}
}
//自动重连
webSocket.reconnect = function () {
//避免ws重复连接
if (heartCheck.lockReconnect) return;
heartCheck.lockReconnect = true;
setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
webSocket.socketInit(true);
heartCheck.lockReconnect = false;
}, heartCheck.connectionTimeout);
if (heartCheck.connectionTimeout >= heartCheck.minReconnectionDelay && heartCheck.connectionTimeout < heartCheck.maxReconnectionDelay) {
heartCheck.connectionTimeout = heartCheck.connectionTimeout * heartCheck.reconnectionDelayGrowFactor
} else {
heartCheck.connectionTimeout = heartCheck.minReconnectionDelay;
}
}
//实际应用
//参数:reconnection 判断是不是自动重连 可以在后期对业务进行不同的处理 例如正常连接走一段代码,断线重连走另一段
webSocket.socketInit = function (reconnection = false) {
return new Promise((resolve, reject) => {
if ("这里可以判断用户网络状态 或者 用户登录情况") {
if (WEB_SOCKET == null) {
WEB_SOCKET = new WebSocket("ws://88.gaoqiaoxue.com/v5/apipost.io?userToken=" + AP.USER.userIndendify);
WEB_SOCKET.onopen = function (evt) {
//console.log("连接成功,发送ping");
WEB_SOCKET.send("PING")
heartCheck.PingStart();
heartCheck.reset().PongStart(); //打开心跳检测
//console.log("Connection open ...", evt, WEB_SOCKET);
resolve(true)
};
WEB_SOCKET.onerror = function (err) {
//console.log(err);
if (WEB_SOCKET != null) {
//console.log("异常,关闭连接", err);
WEB_SOCKET.close();
} else {
webSocket.reconnect(); //打开自动重连
}
reject(err)
}
WEB_SOCKET.onmessage = function (evt) {
if (WEB_SOCKET != null) {
heartCheck.reset().PongStart(); //拿到任何消息都说明当前连接是正常的 心跳检测重置
}
};
WEB_SOCKET.onclose = function (evt) {
//console.log("Connection closed.");
webSocket.reconnect(); //打开自动重连
resolve(true)
};
}
} else {
switch (WEB_SOCKET.readyState) {
case WebSocket.CONNECTING: //表示正在连接。
//console.log("正在连接");
resolve(true)
break;
case WebSocket.OPEN: //表示连接成功,可以通信了。
//console.log("已经连接");
resolve(true)
break;
case WebSocket.CLOSING: //表示连接正在关闭。
//console.log("正在关闭,1秒后再次尝试连接");
setTimeout(() => {
webSocket.socketInit();
}, 1000);
resolve(true)
break;
case WebSocket.CLOSED: //表示连接已经关闭,或者打开连接失败
//console.log("已经关闭,再次连接");
WEB_SOCKET = null;
webSocket.socketInit(true);
resolve(true)
break;
default:
// this never happens
break;
}
} else {
webSocket.reconnect(); //重新连接
reject(false)
}
}).catch((e) => {
webSocket.reconnect(); //重新连接
})
}
代码已经写的很详细了,谢谢观看,如果您还有其他相关问题,欢迎留言