Files
shoot-miniprograms/src/websocket.js

178 lines
4.6 KiB
JavaScript
Raw Normal View History

2025-07-28 09:02:02 +08:00
import { MESSAGETYPES, getMessageTypeName } from "@/constants";
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 reconnectTimer = null;
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
*/
function createWebSocket(token, onMessage) {
2025-08-09 12:16:36 +08:00
let url = "wss://api.shelingxingqiu.com/socket";
try {
const accountInfo = uni.getAccountInfoSync();
const envVersion = accountInfo.miniProgram.envVersion;
switch (envVersion) {
case "develop": // 开发版
2025-08-15 16:37:10 +08:00
// url = "ws://192.168.1.242:8000/socket";
url = "wss://apitest.shelingxingqiu.com/socket";
2025-08-09 12:16:36 +08:00
break;
case "trial": // 体验版
url = "wss://apitest.shelingxingqiu.com/socket";
break;
case "release": // 正式版
url = "wss://api.shelingxingqiu.com/socket";
break;
default:
// 保持默认值
break;
}
} catch (e) {
console.error("获取环境信息失败,使用默认正式环境", e);
}
url += `?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-07-18 13:38:01 +08:00
startHeartbeat(onMessage);
},
fail: () => {
reconnect(onMessage);
2025-06-18 00:35:16 +08:00
},
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);
2025-07-12 17:12:24 +08:00
if (data.event === "pong" || !data.data.updates) return;
2025-06-19 21:03:33 +08:00
if (onMessage) onMessage(data.data.updates);
2025-07-03 21:13:55 +08:00
const msg = data.data.updates[0];
2025-07-12 17:12:24 +08:00
if (!msg) return;
2025-07-28 09:02:02 +08:00
console.log("收到消息:", getMessageTypeName(msg.constructor), msg);
2025-07-12 17:12:24 +08:00
if (msg.constructor === MESSAGETYPES.BackToGame) {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
if (
currentPage.route === "pages/battle-room" ||
2025-08-14 10:50:44 +08:00
currentPage.route === "pages/team-battle" ||
currentPage.route === "pages/melee-match"
) {
return;
}
2025-07-03 21:13:55 +08:00
const { battleInfo } = msg;
2025-07-15 18:14:59 +08:00
uni.setStorageSync("current-battle", battleInfo);
2025-11-05 14:27:58 +08:00
// console.log("----battleInfo", battleInfo);
2025-07-28 13:54:37 +08:00
if (battleInfo.config.mode === 1) {
2025-07-03 21:13:55 +08:00
uni.navigateTo({
2025-08-14 10:50:44 +08:00
url: `/pages/team-battle?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
2025-07-28 13:54:37 +08:00
});
} else if (battleInfo.config.mode === 2) {
uni.navigateTo({
url: `/pages/melee-match?battleId=${battleInfo.id}&gameMode=${battleInfo.config.battleMode}`,
2025-07-03 21:13:55 +08:00
});
}
2025-07-22 09:36:38 +08:00
} else if (msg.constructor === MESSAGETYPES.MatchOver) {
uni.$emit("game-over");
2025-07-22 09:36:38 +08:00
} else if (msg.constructor === MESSAGETYPES.RankUpdate) {
2025-07-23 20:47:31 +08:00
uni.setStorageSync("latestRank", msg.lvl);
2025-07-22 09:36:38 +08:00
} else if (msg.constructor === MESSAGETYPES.LvlUpdate) {
2025-07-23 20:47:31 +08:00
uni.setStorageSync("latestLvl", msg.lvl);
2025-12-31 13:39:16 +08:00
} else if (msg.constructor === MESSAGETYPES.DeviceOnline) {
uni.$emit("update-online");
} else if (msg.constructor === MESSAGETYPES.DeviceOffline) {
uni.$emit("update-online");
2025-07-12 17:12:24 +08:00
}
2025-05-28 23:49:17 +08:00
});
// 错误处理
uni.onSocketError((err) => {
console.error("WebSocket 错误", err);
2025-07-18 13:38:01 +08:00
reconnect(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-18 00:35:16 +08:00
stopHeartbeat();
reconnect(onMessage);
2025-05-28 23:49:17 +08:00
});
2025-05-29 23:45:44 +08:00
}
2025-06-18 00:35:16 +08:00
/**
* 重连机制
*/
function reconnect(onMessage) {
2025-06-18 00:35:16 +08:00
reconnectTimer && clearTimeout(reconnectTimer);
2025-07-18 13:38:01 +08:00
closeWebSocket(); // 确保关闭旧连接
2025-06-18 00:35:16 +08:00
2025-09-12 17:49:26 +08:00
const token = uni.getStorageSync(
`${uni.getAccountInfoSync().miniProgram.envVersion}_token`
);
2025-06-22 02:39:03 +08:00
if (!token) return;
2025-07-18 13:38:01 +08:00
2025-06-18 00:35:16 +08:00
reconnectTimer = setTimeout(() => {
console.log("reconnecting...");
createWebSocket(token, onMessage);
2025-07-18 13:38:01 +08:00
}, 1000);
2025-06-18 00:35:16 +08:00
}
2025-05-29 23:45:44 +08:00
function closeWebSocket() {
2025-05-30 13:58:43 +08:00
if (socket) {
2025-06-22 02:39:03 +08:00
reconnectTimer && clearTimeout(reconnectTimer);
stopHeartbeat();
2025-07-18 13:38:01 +08:00
try {
socket.close();
} catch (err) {
console.error("关闭WebSocket连接失败", err);
}
socket = null; // 清除socket引用
2025-05-30 13:58:43 +08:00
}
2025-05-28 23:49:17 +08:00
}
2025-07-18 13:38:01 +08:00
function sendHeartbeat(onMessage) {
uni.sendSocketMessage({
data: JSON.stringify({ event: "ping", data: {} }),
success: () => {
// console.log("发送心跳成功");
},
fail: (err) => {
console.error("发送心跳失败", err);
stopHeartbeat();
closeWebSocket(); // 关闭失效的连接
reconnect(onMessage); // 触发重连
},
});
}
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-07-18 13:38:01 +08:00
function startHeartbeat(onMessage) {
2025-05-29 23:45:44 +08:00
stopHeartbeat(); // 防止重复启动
heartbeatInterval = setInterval(() => {
2025-07-18 13:38:01 +08:00
if (socket && socket.readyState === 1) {
// 检查连接状态
sendHeartbeat(onMessage);
2025-05-29 23:45:44 +08:00
}
2025-07-05 18:51:06 +08:00
}, 10000);
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,
};