import { MESSAGETYPES } from "@/constants"; let socket = null; let heartbeatInterval = null; let reconnectCount = 0; let reconnectTimer = null; // 重连配置 const RECONNECT_CONFIG = { MAX_COUNT: 999, // 最大重连次数 INITIAL_DELAY: 2000, // 初始重连延迟(2秒) MAX_DELAY: 5000, // 最大重连延迟(5秒) }; /** * 建立 WebSocket 连接 */ function createWebSocket(token, onMessage) { const url = `wss://api.shelingxingqiu.com/socket?authorization=${token}`; socket = uni.connectSocket({ url, success: () => { console.log("websocket 连接成功"); reconnectCount = 0; // 重置重连次数 // 启动心跳 startHeartbeat(); }, 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; if (msg.constructor === MESSAGETYPES.BackToGame) { const { battleInfo } = msg; uni.setStorageSync("current-battle", battleInfo); // 约战 if (battleInfo.config.battleMode === 1) { uni.navigateTo({ url: `/pages/battle-room?battleId=${battleInfo.id}`, }); } // 排位 if (battleInfo.config.battleMode === 2) { if (battleInfo.config.mode === 1) { uni.navigateTo({ url: `/pages/team-match?battleId=${battleInfo.id}`, }); } else if (battleInfo.config.mode === 2) { uni.navigateTo({ url: `/pages/melee-match?battleId=${battleInfo.id}`, }); } } } if (msg.constructor === MESSAGETYPES.PaySuccess) { console.log(1111111, msg); } }); // 错误处理 uni.onSocketError((err) => { console.error("WebSocket 错误", err); reconnect(token, onMessage); }); uni.onSocketClose((result) => { console.log("WebSocket 已关闭", result); stopHeartbeat(); reconnect(onMessage); }); } /** * 重连机制 */ function reconnect(onMessage) { if (reconnectCount >= RECONNECT_CONFIG.MAX_COUNT) return; reconnectTimer && clearTimeout(reconnectTimer); const token = uni.getStorageSync("token"); if (!token) return; // 计算重连延迟(指数退避) const delay = Math.min( RECONNECT_CONFIG.INITIAL_DELAY * Math.pow(2, reconnectCount), RECONNECT_CONFIG.MAX_DELAY ); reconnectTimer = setTimeout(() => { console.log("reconnecting..."); createWebSocket(token, onMessage); reconnectCount++; }, delay); } function closeWebSocket() { if (socket) { // 清理重连定时器 reconnectCount = 0; reconnectTimer && clearTimeout(reconnectTimer); stopHeartbeat(); socket.close(); } } /** * 启动心跳 */ function startHeartbeat() { stopHeartbeat(); // 防止重复启动 heartbeatInterval = setInterval(() => { if (socket) { uni.sendSocketMessage({ data: JSON.stringify({ event: "ping", data: {} }), fail: (err) => { console.error("发送心跳失败", err); }, }); } }, 10000); } /** * 停止心跳 */ function stopHeartbeat() { if (heartbeatInterval) { clearInterval(heartbeatInterval); heartbeatInterval = null; } } export default { createWebSocket, closeWebSocket, };