Files
shoot-miniprograms/src/websocket.js

117 lines
2.5 KiB
JavaScript
Raw Normal View History

2025-05-28 23:49:17 +08:00
let socket = null;
2025-05-29 23:45:44 +08:00
let heartbeatInterval = null;
2025-06-18 00:35:16 +08:00
let reconnectCount = 0;
let reconnectTimer = null;
// 重连配置
const RECONNECT_CONFIG = {
2025-06-24 13:18:03 +08:00
MAX_COUNT: 999, // 最大重连次数
2025-06-18 00:35:16 +08:00
INITIAL_DELAY: 2000, // 初始重连延迟2秒
2025-06-24 13:18:03 +08:00
MAX_DELAY: 5000, // 最大重连延迟5秒
2025-06-18 00:35:16 +08:00
};
2025-05-28 23:49:17 +08:00
/**
2025-05-29 23:45:44 +08:00
* 建立 WebSocket 连接
2025-05-28 23:49:17 +08:00
*/
2025-06-19 21:03:33 +08:00
function createWebSocket(token, onUpdate, onMessage) {
2025-06-14 22:45:16 +08:00
const url = `wss://api.shelingxingqiu.com/socket?authorization=${token}`;
2025-05-28 23:49:17 +08:00
socket = uni.connectSocket({
2025-06-14 22:45:16 +08:00
url,
2025-06-18 00:35:16 +08:00
success: () => {
console.log("websocket 连接成功");
2025-06-19 21:03:33 +08:00
onUpdate(true);
2025-06-18 00:35:16 +08:00
reconnectCount = 0; // 重置重连次数
},
2025-05-28 23:49:17 +08:00
});
// 接收消息
uni.onSocketMessage((res) => {
2025-06-19 21:03:33 +08:00
const data = JSON.parse(res.data);
if (onMessage) onMessage(data.data.updates);
2025-05-28 23:49:17 +08:00
});
// 错误处理
uni.onSocketError((err) => {
console.error("WebSocket 错误", err);
2025-06-18 00:35:16 +08:00
reconnect(token, onMessage);
2025-05-28 23:49:17 +08:00
});
2025-06-05 17:43:22 +08:00
uni.onSocketClose((result) => {
console.log("WebSocket 已关闭", result);
2025-06-19 21:03:33 +08:00
onUpdate(false);
2025-06-18 00:35:16 +08:00
stopHeartbeat();
2025-06-22 10:57:42 +08:00
reconnect(onUpdate, onMessage);
2025-05-28 23:49:17 +08:00
});
2025-05-29 23:45:44 +08:00
// 启动心跳
startHeartbeat();
}
2025-06-18 00:35:16 +08:00
/**
* 重连机制
*/
2025-06-22 10:57:42 +08:00
function reconnect(onUpdate, onMessage) {
2025-06-18 00:35:16 +08:00
if (reconnectCount >= RECONNECT_CONFIG.MAX_COUNT) return;
reconnectTimer && clearTimeout(reconnectTimer);
2025-06-22 02:39:03 +08:00
const token = uni.getStorageSync("token");
if (!token) return;
2025-06-18 00:35:16 +08:00
// 计算重连延迟(指数退避)
const delay = Math.min(
RECONNECT_CONFIG.INITIAL_DELAY * Math.pow(2, reconnectCount),
RECONNECT_CONFIG.MAX_DELAY
);
reconnectTimer = setTimeout(() => {
console.log("reconnecting...");
2025-06-22 10:57:42 +08:00
createWebSocket(token, onUpdate, onMessage);
2025-06-18 00:35:16 +08:00
reconnectCount++;
}, delay);
}
2025-05-29 23:45:44 +08:00
function closeWebSocket() {
2025-05-30 13:58:43 +08:00
if (socket) {
2025-06-18 00:35:16 +08:00
// 清理重连定时器
reconnectCount = 0;
2025-06-22 02:39:03 +08:00
reconnectTimer && clearTimeout(reconnectTimer);
stopHeartbeat();
socket.close();
2025-05-30 13:58:43 +08:00
}
2025-05-28 23:49:17 +08:00
}
/**
2025-05-29 23:45:44 +08:00
* 启动心跳
2025-05-28 23:49:17 +08:00
*/
2025-05-29 23:45:44 +08:00
function startHeartbeat() {
stopHeartbeat(); // 防止重复启动
heartbeatInterval = setInterval(() => {
if (socket && uni.sendSocketMessage) {
uni.sendSocketMessage({
2025-06-05 17:43:22 +08:00
data: {
event: "ping",
data: {},
},
2025-05-29 23:45:44 +08:00
fail: (err) => {
console.error("发送心跳失败", err);
},
});
}
}, 5000);
2025-05-28 23:49:17 +08:00
}
/**
2025-05-29 23:45:44 +08:00
* 停止心跳
2025-05-28 23:49:17 +08:00
*/
2025-05-29 23:45:44 +08:00
function stopHeartbeat() {
if (heartbeatInterval) {
clearInterval(heartbeatInterval);
heartbeatInterval = null;
2025-05-28 23:49:17 +08:00
}
}
export default {
2025-05-29 23:45:44 +08:00
createWebSocket,
2025-05-28 23:49:17 +08:00
closeWebSocket,
};