let socket = null; let heartbeatInterval = null; let reconnectCount = 0; let reconnectTimer = null; // 重连配置 const RECONNECT_CONFIG = { MAX_COUNT: 10, // 最大重连次数 INITIAL_DELAY: 2000, // 初始重连延迟(2秒) MAX_DELAY: 60000, // 最大重连延迟(1分钟) }; /** * 建立 WebSocket 连接 */ function createWebSocket(token, onUpdate, onMessage) { const url = `wss://api.shelingxingqiu.com/socket?authorization=${token}`; socket = uni.connectSocket({ url, success: () => { console.log("websocket 连接成功"); onUpdate(true); reconnectCount = 0; // 重置重连次数 }, }); // 接收消息 uni.onSocketMessage((res) => { const data = JSON.parse(res.data); if (onMessage) onMessage(data.data.updates); }); // 错误处理 uni.onSocketError((err) => { console.error("WebSocket 错误", err); reconnect(token, onMessage); }); uni.onSocketClose((result) => { console.log("WebSocket 已关闭", result); onUpdate(false); stopHeartbeat(); reconnect(onUpdate, onMessage); }); // 启动心跳 startHeartbeat(); } /** * 重连机制 */ function reconnect(onUpdate, 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, onUpdate, onMessage); reconnectCount++; }, delay); } function closeWebSocket() { if (socket) { // 清理重连定时器 reconnectCount = 0; reconnectTimer && clearTimeout(reconnectTimer); stopHeartbeat(); socket.close(); } } /** * 启动心跳 */ function startHeartbeat() { stopHeartbeat(); // 防止重复启动 heartbeatInterval = setInterval(() => { if (socket && uni.sendSocketMessage) { uni.sendSocketMessage({ data: { event: "ping", data: {}, }, fail: (err) => { console.error("发送心跳失败", err); }, }); } }, 5000); } /** * 停止心跳 */ function stopHeartbeat() { if (heartbeatInterval) { clearInterval(heartbeatInterval); heartbeatInterval = null; } } export default { createWebSocket, closeWebSocket, };