|
|
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连接。
|