import { MESSAGETYPES, getMessageTypeName } from "@/constants"; let socket = null; let heartbeatInterval = null; let reconnectTimer = null; /** * 建立 WebSocket 连接 */ function createWebSocket(token, onMessage) { const url = `wss://api.shelingxingqiu.com/socket?authorization=${token}`; socket = uni.connectSocket({ url, success: () => { console.log("websocket 连接成功"); // 启动心跳 startHeartbeat(onMessage); }, fail: () => { reconnect(onMessage); }, }); // 接收消息 uni.onSocketMessage((res) => { const data = JSON.parse(res.data); if (data.event === "pong" || !data.data.updates) return; if (onMessage) onMessage(data.data.updates); const msg = data.data.updates[0]; if (!msg) return; console.log("收到消息:", getMessageTypeName(msg.constructor), msg); if (msg.constructor === MESSAGETYPES.BackToGame) { const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; if ( currentPage.route === "pages/battle-room" || currentPage.route === "pages/team-match" || currentPage.route === "pages/melee-match" ) { return; } const { battleInfo } = msg; uni.setStorageSync("current-battle", battleInfo); console.log("----battleInfo", battleInfo); if (battleInfo.config.mode === 1) { uni.navigateTo({ url: `/pages/team-match?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`, }); } else if (battleInfo.config.mode === 2) { uni.navigateTo({ url: `/pages/melee-match?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`, }); } } else if (msg.constructor === MESSAGETYPES.MatchOver) { uni.$emit("game-over"); } else if (msg.constructor === MESSAGETYPES.RankUpdate) { uni.setStorageSync("latestRank", msg.lvl); } else if (msg.constructor === MESSAGETYPES.LvlUpdate) { uni.setStorageSync("latestLvl", msg.lvl); } }); // 错误处理 uni.onSocketError((err) => { console.error("WebSocket 错误", err); reconnect(onMessage); }); uni.onSocketClose((result) => { console.log("WebSocket 已关闭", result); stopHeartbeat(); reconnect(onMessage); }); } /** * 重连机制 */ function reconnect(onMessage) { reconnectTimer && clearTimeout(reconnectTimer); closeWebSocket(); // 确保关闭旧连接 const token = uni.getStorageSync("token"); if (!token) return; reconnectTimer = setTimeout(() => { console.log("reconnecting..."); createWebSocket(token, onMessage); }, 1000); } function closeWebSocket() { if (socket) { reconnectTimer && clearTimeout(reconnectTimer); stopHeartbeat(); try { socket.close(); } catch (err) { console.error("关闭WebSocket连接失败", err); } socket = null; // 清除socket引用 } } function sendHeartbeat(onMessage) { uni.sendSocketMessage({ data: JSON.stringify({ event: "ping", data: {} }), success: () => { // console.log("发送心跳成功"); }, fail: (err) => { console.error("发送心跳失败", err); stopHeartbeat(); closeWebSocket(); // 关闭失效的连接 reconnect(onMessage); // 触发重连 }, }); } /** * 启动心跳 */ function startHeartbeat(onMessage) { stopHeartbeat(); // 防止重复启动 heartbeatInterval = setInterval(() => { if (socket && socket.readyState === 1) { // 检查连接状态 sendHeartbeat(onMessage); } }, 10000); } /** * 停止心跳 */ function stopHeartbeat() { if (heartbeatInterval) { clearInterval(heartbeatInterval); heartbeatInterval = null; } } export default { createWebSocket, closeWebSocket, };