1.创建 utils/webSocket.ts
import { ctMsg } from "@/utils/custom/message"
import { getToken } from "./auth"let socket = null // WebSocket 实例对象
let lockReconnect = false // 是否正在重连
const timeout = 20 * 1000 // 20秒一次心跳
let timeoutObj = null // 心跳定时器
let serverTimeoutObj = null // 服务超时定时器
let timeoutnum = null // 断开重连定时器// 初始化 WebSocket 连接
const initWebSocket = async (data?:any) => {if ("WebSocket" in window) {const wsUrl = `ws://172.16.3.101:8081/api/galaxy?${data}` // WebSocket 连接地址socket = new WebSocket(wsUrl)socket.onerror = webSocketOnErrorsocket.onmessage = webSocketOnMessagesocket.onclose = closeWebsocketsocket.onopen = openWebsocket} else {ctMsg("浏览器不支持 WebSocket")}
}// WebSocket 连接成功时的回调
const openWebsocket = (e) => {console.log("WebSocket 连接成功", e)start() // 启动心跳检测
}// 启动心跳检测
const start = () => {// 清除上一次的定时器clearTimeout(timeoutObj)clearTimeout(serverTimeoutObj)// 发送心跳消息,保证连接活跃timeoutObj = setTimeout(() => {if (socket.readyState === WebSocket.OPEN) {socket.send("heartbeat") // 发送心跳消息} else {reconnect() // 如果连接不可用,则重连}// 超过指定时间(timeout)未收到响应,则认为连接失效,主动关闭serverTimeoutObj = setTimeout(() => {socket.close()}, timeout)}, timeout)
}// 重新连接 WebSocket
const reconnect = () => {if (lockReconnect) return // 防止并发重连lockReconnect = truetimeoutnum && clearTimeout(timeoutnum) // 清除已有的重连定时器timeoutnum = setTimeout(() => {initWebSocket() // 尝试重新连接lockReconnect = false}, 1000) // 延迟1秒后重连
}// 重置心跳定时器
const reset = () => {clearTimeout(timeoutObj)clearTimeout(serverTimeoutObj)start() // 重新启动心跳检测
}// 发送消息
const sendWebsocket = (message) => {if (socket && socket.readyState === WebSocket.OPEN) {console.log("发送消息:", message)socket.send(message)} else {console.error("WebSocket 连接未打开,无法发送消息")}
}// WebSocket 错误处理
const webSocketOnError = (e) => {console.error("WebSocket 错误:", e)reconnect() // 出现错误时尝试重连
}// 服务器返回消息的处理
const webSocketOnMessage = (e) => {try {const messageData = JSON.parse(e?.data) // 解析消息内容if (getToken()) { // 如果存在 Token,广播自定义事件window.dispatchEvent(new CustomEvent("onmessageWS", {detail: { data: messageData }}))}reset() // 收到消息后重置心跳定时器} catch (error) {console.error("解析 WebSocket 消息失败:", error)}
}// WebSocket 连接关闭时的处理
const closeWebsocket = (e) => {console.log("WebSocket 连接关闭:", e)reconnect() // 连接关闭后重连
}// 手动关闭 WebSocket 连接
const close = () => {clearTimeout(timeoutObj)clearTimeout(serverTimeoutObj)if (socket) {socket.close() // 主动关闭连接}
}export default { initWebSocket, sendWebsocket, webSocketOnMessage, close }
2.在页面中使用
引入
import websocket from "@/utils/websocket"页面调用
onMounted(async () => {
websocket.initWebSocket("nanoid=111")
})
拿取数据
window.addEventListener(
"mousewheel",
function (event) {
if (event.ctrlKey === true || event.metaKey) {
event.preventDefault()
}
},
{
passive: false
}
)
离开销毁onUnmounted(() => {
websocket.close()
})