You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
3.8 KiB
JavaScript

12 months ago
import { Notification } from "element-ui";
let hasShownNotification = false;
// WebSocket连接实例
let socket = null;
// 是否正在尝试重连
let lockReconnect = false;
// 心跳间隔20秒
const timeout = 20 * 1000;
// 心跳定时器
let timeoutObj = null;
// 服务器无响应超时定时器
let serverTimeoutObj = null;
// 重连定时器
let reconnectTimeout = null;
// 初始化WebSocket连接
const initWebSocket = () => {
if ("WebSocket" in window) {
const protocol = window.location.protocol === "https:" ? "wss://" : "ws://";
const wsPath = "/api/xymanager/websocket";
const wshost =
window.location.hostname === "localhost"
? "61.169.135.146:40085"
: window.location.host;
const wsUrl = protocol + wshost + wsPath;
socket = new WebSocket(wsUrl);
socket.onerror = webSocketOnError;
socket.onmessage = webSocketOnMessage;
socket.onclose = closeWebsocket;
socket.onopen = openWebsocket;
} else {
// 浏览器不支持WebSocket
console.error("您的浏览器不支持WebSocket");
// 这里可以添加更友好的提示方式如使用Element UI的Notification
}
};
// 打开WebSocket连接时执行
const openWebsocket = () => {
console.log("WebSocket链接成功");
startHeartbeat();
};
// 启动心跳
const startHeartbeat = () => {
timeoutObj = setTimeout(() => {
if (socket.readyState === WebSocket.OPEN) {
socket.send("1"); // 发送心跳消息
console.log("发送心跳消息以保持WebSocket连接活跃");
// 如果需要,可以在这里添加检测服务器响应的逻辑
// 例如,设置一个服务器响应超时检测
// 递归调用以继续发送心跳
startHeartbeat();
} else {
// 如果WebSocket已经关闭则不再发送心跳
console.log("WebSocket连接已关闭停止发送心跳");
clearTimeout(timeoutObj); // 清除定时器
}
}, timeout);
};
// WebSocket错误处理
const webSocketOnError = (e) => {
console.error("WebSocket发生错误:", e);
// 这里通常不需要立即重连因为onclose会处理重连逻辑
};
// 处理接收到的消息
const webSocketOnMessage = (e) => {
// 自定义事件,将接收到的数据派发给其他监听器
window.dispatchEvent(
new CustomEvent("onmessageWS", { detail: { data: e.data } })
);
// 收到消息后重置心跳定时器
resetHeartbeat();
};
// WebSocket关闭处理
const closeWebsocket = (e) => {
console.log("WebSocket连接已关闭:", e);
// if (!hasShownNotification) {
// Notification({
// title: "告警",
// message: "WebSocket连接已关闭",
// position: "bottom-right",
// type: "warning",
// duration: 2000,
// });
// hasShownNotification = true; // 更新状态,防止再次显示
// }
// 清除所有定时器
clearTimeout(timeoutObj);
clearTimeout(serverTimeoutObj);
// 设置重连定时器
reconnectTimeout = setTimeout(() => {
initWebSocket();
}, 60 * 1000); // 60秒后重连
};
// 重置心跳定时器
const resetHeartbeat = () => {
clearTimeout(timeoutObj);
clearTimeout(serverTimeoutObj);
startHeartbeat();
};
// 发送消息到WebSocket服务器
const sendWebsocket = (data) => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(data);
} else {
console.error("WebSocket未连接无法发送消息");
}
};
// 关闭WebSocket连接通常不需要在前端主动调用除非有特定需求
const close = () => {
if (socket) {
socket.close();
}
};
// 导出相关函数,以便在其他地方使用
export default { initWebSocket, sendWebsocket, close };
// 注意关于离开页面不断开WebSocket连接的需求这通常取决于浏览器的行为。
// 在一些情况下浏览器会在页面卸载时自动关闭WebSocket连接。