1、websocket工具 config > index.ts、utils>websocket>index.ts
import { ElMessage, getCache } from "@/utils";
function webSocket(params: string) {
let urlParams: string = params
const is_reconnect = ref(true); // 是否⾃动重连
let reconnection: any; // 断线重连后,延迟5秒重新创建WebSocket连接
let ws: any; // 用于存储实例化后websocket
let websocketConnectdCount = 0;
let serverTimeoutObj: any = null;
let hearbeat_interval = 300000; // ⼼跳发送频率 一分钟
const init = () => {
if (!("WebSocket" in window)) {
ElMessage({
message: "抱歉,浏览器不支持Websocket!",
type: "warning",
duration: 1000,
});
return;
}
try {
// 初始化websocket连接
initWebSocket();
} catch (e) {
console.log("尝试创建连接失败");
reConnect(); // 如果无法连接上 webSocket 重连
}
};
// 初始化websocket
function initWebSocket() {
let baseUrl = import.meta.env.VITE_BaseUrl?.slice(7)
let url = `ws://${baseUrl}/websocket/${urlParams}`
ws = new WebSocket(url);
ws.onopen = function (e: any) {
websocketOpen(e);
};
// 接收
ws.onmessage = function (e: any) {
websocketonmessage(e);
};
// 连接发生错误
ws.onerror = function () {
console.log("WebSocket连接发生错误");
is_reconnect.value = false; // 连接断开修改标识
websocketConnectdCount++;
if (websocketConnectdCount <= 5) {
reConnect(); // 连接错误 需要重连
}
};
ws.onclose = function (e: any) {
websocketclose(e);
};
}
// 创建连接
function websocketOpen(e: any) {
console.log("连接成功");
reset();
start();
const data = {
sendType: "HEALTH",
};
ws.send(JSON.stringify(data));
}
// 数据接收
const onMessageFns = new Set();
function websocketonmessage(e: any) {
if (onMessageFns.size) {
onMessageFns.forEach((callback) => {
//@ts-ignore
callback(e);
});
}
// 如果获取到消息,说明连接是正常的,重置心跳检测
reset();
start();
return e.data;
}
// 关闭
function websocketclose(e: any) {
console.log(e);
is_reconnect.value = false; // 断开后修改标识
console.log("connection closed (" + e.code + ")");
}
// 数据发送
function websocketsend(data: any) {
if (!["number", "string"].includes(typeof data)) {
data = JSON.stringify(data);
}
ws.send(data);
}
// 发送
function sendWebSocket(data: any) {
if (ws.readyState === ws.OPEN) {
// 开启状态
websocketsend(data);
} else {
// 若 未开启 / 正在开启 状态 ,则等待1s后重新调用
setTimeout(function () {
sendWebSocket(data);
}, 1000);
}
}
// 定义重连函数
let reConnect = () => {
console.log("尝试重新连接");
if (is_reconnect) return; // 如果已经连上就不在重连了
reconnection && clearTimeout(reconnection);
reconnection = setTimeout(function () {
// 延迟5秒重连 避免过多次过频繁请求重连
init();
}, 5000);
};
window.onbeforeunload = function () {
ws.close();
};
//心跳
let reset = () => {
clearTimeout(serverTimeoutObj);
};
const start = () => {
serverTimeoutObj = setInterval(() => {
if (ws.readyState === 1) {
console.log("连接状态,发送消息保持连接");
const data = {
sendType: "HEALTH",
};
ws.send(JSON.stringify(data));
reset(); // 如果获得消息 说明连接正常 重置心跳检测
} else {
console.log("断开连接, 尝试重连");
webSocket(urlParams);
}
}, hearbeat_interval);
};
init();
return {
sendWebSocket,
onMessageFns,
};
}
export default webSocket;
3、页面使用
import webSocket from "@/utils/websocket";
const userId = getCache("userId");
const ws = webSocket(userId)!;
onMounted(async () => {
const addMessage = () => {
ws.onMessageFns.add((value: any) => {
if (value.data !== "来自后台的反馈:连接成功" && value.data !== "SUCCESS") {
if (JSON.parse(value.data)) {
console.log("获取到的信息",JSON.parse(value.data))
}
}
});
};
});