webSocket.js
import { Message } from 'element-ui'
let socket = null;//实例对象
let socketLeaveFlag = false
let socketReconnectTimer = null // 计时器对象——重连
let socketReconnectLock = false // WebSocket重连的锁
const heartCheck = {
vueThis: this, // vue实例
timeout: 10000, // 超时时间
timeoutObj: null, // 计时器对象——向后端发送心跳检测
serverTimeoutObj: null, // 计时器对象——等待后端心跳检测的回复
// 心跳检测重置
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
// 心跳检测启动
start: function () {
this.timeoutObj && clearTimeout(this.timeoutObj);
this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
this.timeoutObj = setTimeout(() => {
// 这里向后端发送一个心跳检测,后端收到后,会返回一个心跳回复
socket.send("HeartBeat");
console.log("发送心跳检测");
this.serverTimeoutObj = setTimeout(() => {
// 如果超过一定时间还没重置计时器,说明websocket与后端断开了
console.log("未收到心跳检测回复");
// 关闭WebSocket
socket.close();
}, this.timeout);
}, this.timeout);
},
}
const initWebSocket = (wsUrl) => {
return new Promise(function (resolve, reject) {
if ("WebSocket" in window) {
socket = new WebSocket(wsUrl);
socket.onerror = webSocketOnError;
socket.onmessage = webSocketOnMessage;
socket.onclose = webSocketOnClose;
socket.onopen = () => {
console.log('连接成功');
heartCheck.reset().start();
resolve(socket)
};
} else {
Message({
message: "您的浏览器不支持websocket,请更换Chrome或者Firefox",
type: 'error',
})
return reject(new Error('浏览器不支持websocket'));
}
});
}
const webSocketOnError = (e) => {
console.log("WebSocket:发生错误");
socketReconnect(e.target.url)
window.dispatchEvent(
new CustomEvent("WSOnError", e)
);
}
//服务器返回的数据
const webSocketOnMessage = (e) => {
let detail = JSON.parse(e.data)
if (detail.key === 'WEBSOCKET_HEARTBEAT_RECOVERY') {
console.log('收到心跳回复');
heartCheck.reset().start();
} else {
window.dispatchEvent(
new CustomEvent("WSOnMessage", { detail })
);
}
}
const webSocketOnClose = (e) => {
console.log("WebSocket:已关闭");
// 清除心跳定时器
heartCheck.reset();
if (!socketLeaveFlag) {
// websocket重连
socketReconnect(e.target.url)
}
}
const socketReconnect = (url) => {
if (socketReconnectLock) {
return;
}
socketReconnectLock = true;
socketReconnectTimer && clearTimeout(socketReconnectTimer);
socketReconnectTimer = setTimeout(() => {
console.log("WebSocket:重连中...");
socketReconnectLock = false;
// websocket启动
initWebSocket(url);
}, 4000);
}
const closeWebSocket = () => {
socketLeaveFlag = true
if (socket) {
console.log('断开连接');
socket.close();
}
}
//具体问题具体分析,把需要用到的方法暴露出去
export default { closeWebSocket, socket, initWebSocket };
使用方式
import websocket from '@/utils/webSocket';
function WSOnMessage({ detail }) {
// console.log(detail)
}
//初始化,初始化后任意页面均可监听消息
websocket.initWebSocket(url)
//添加事件监听,根据业务需求添加事件移除逻辑
window.addEventListener("WSOnMessage", WSOnMessage)