websocket逻辑优化

This commit is contained in:
kron
2025-07-18 13:38:01 +08:00
parent ccfd09bb01
commit 4f4178b75d
3 changed files with 42 additions and 41 deletions

View File

@@ -1,6 +1,6 @@
<script setup> <script setup>
import { watch } from "vue"; import { watch } from "vue";
import { onShow } from "@dcloudio/uni-app"; import { onShow, onHide } from "@dcloudio/uni-app";
import websocket from "@/websocket"; import websocket from "@/websocket";
import useStore from "@/store"; import useStore from "@/store";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
@@ -30,18 +30,16 @@ watch(
onShow(() => { onShow(() => {
const token = uni.getStorageSync("token"); const token = uni.getStorageSync("token");
if (user.value.id && token) { if (user.value.id && token) {
// 检查 WebSocket 连接状态 console.log("回到前台,重新连接 websocket");
uni.sendSocketMessage({ websocket.createWebSocket(token, (content) => {
data: JSON.stringify({ event: "ping", data: {} }), uni.$emit("socket-inbox", content);
fail: () => {
// 如果发送失败,说明连接已断开,需要重新连接
websocket.createWebSocket(token, (content) => {
uni.$emit("socket-inbox", content);
});
},
}); });
} }
}); });
onHide(() => {
websocket.closeWebSocket();
});
</script> </script>
<style> <style>

View File

@@ -13,6 +13,7 @@ export const checkConnection = () => {
uni.sendSocketMessage({ uni.sendSocketMessage({
data: JSON.stringify({ event: "ping", data: {} }), data: JSON.stringify({ event: "ping", data: {} }),
fail: () => { fail: () => {
websocket.closeWebSocket();
const token = uni.getStorageSync("token"); const token = uni.getStorageSync("token");
if (!token) return; if (!token) return;
// 如果发送失败,说明连接已断开,需要重新连接 // 如果发送失败,说明连接已断开,需要重新连接

View File

@@ -1,16 +1,8 @@
import { MESSAGETYPES } from "@/constants"; import { MESSAGETYPES } from "@/constants";
let socket = null; let socket = null;
let heartbeatInterval = null; let heartbeatInterval = null;
let reconnectCount = 0;
let reconnectTimer = null; let reconnectTimer = null;
// 重连配置
const RECONNECT_CONFIG = {
MAX_COUNT: 999, // 最大重连次数
INITIAL_DELAY: 2000, // 初始重连延迟2秒
MAX_DELAY: 5000, // 最大重连延迟5秒
};
/** /**
* 建立 WebSocket 连接 * 建立 WebSocket 连接
*/ */
@@ -20,9 +12,8 @@ function createWebSocket(token, onMessage) {
url, url,
success: () => { success: () => {
console.log("websocket 连接成功"); console.log("websocket 连接成功");
reconnectCount = 0; // 重置重连次数
// 启动心跳 // 启动心跳
startHeartbeat(); startHeartbeat(onMessage);
}, },
fail: () => { fail: () => {
reconnect(onMessage); reconnect(onMessage);
@@ -32,6 +23,7 @@ function createWebSocket(token, onMessage) {
// 接收消息 // 接收消息
uni.onSocketMessage((res) => { uni.onSocketMessage((res) => {
const data = JSON.parse(res.data); const data = JSON.parse(res.data);
// console.log(res);
if (data.event === "pong" || !data.data.updates) return; if (data.event === "pong" || !data.data.updates) return;
if (onMessage) onMessage(data.data.updates); if (onMessage) onMessage(data.data.updates);
const msg = data.data.updates[0]; const msg = data.data.updates[0];
@@ -66,7 +58,7 @@ function createWebSocket(token, onMessage) {
// 错误处理 // 错误处理
uni.onSocketError((err) => { uni.onSocketError((err) => {
console.error("WebSocket 错误", err); console.error("WebSocket 错误", err);
reconnect(token, onMessage); reconnect(onMessage);
}); });
uni.onSocketClose((result) => { uni.onSocketClose((result) => {
@@ -80,48 +72,58 @@ function createWebSocket(token, onMessage) {
* 重连机制 * 重连机制
*/ */
function reconnect(onMessage) { function reconnect(onMessage) {
if (reconnectCount >= RECONNECT_CONFIG.MAX_COUNT) return;
reconnectTimer && clearTimeout(reconnectTimer); reconnectTimer && clearTimeout(reconnectTimer);
closeWebSocket(); // 确保关闭旧连接
const token = uni.getStorageSync("token"); const token = uni.getStorageSync("token");
if (!token) return; if (!token) return;
// 计算重连延迟(指数退避)
const delay = Math.min(
RECONNECT_CONFIG.INITIAL_DELAY * Math.pow(2, reconnectCount),
RECONNECT_CONFIG.MAX_DELAY
);
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
console.log("reconnecting..."); console.log("reconnecting...");
createWebSocket(token, onMessage); createWebSocket(token, onMessage);
reconnectCount++; }, 1000);
}, delay);
} }
function closeWebSocket() { function closeWebSocket() {
if (socket) { if (socket) {
// 清理重连定时器
reconnectCount = 0;
reconnectTimer && clearTimeout(reconnectTimer); reconnectTimer && clearTimeout(reconnectTimer);
stopHeartbeat(); stopHeartbeat();
socket.close();
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() { function startHeartbeat(onMessage) {
stopHeartbeat(); // 防止重复启动 stopHeartbeat(); // 防止重复启动
heartbeatInterval = setInterval(() => { heartbeatInterval = setInterval(() => {
if (socket) { if (socket && socket.readyState === 1) {
uni.sendSocketMessage({ // 检查连接状态
data: JSON.stringify({ event: "ping", data: {} }), sendHeartbeat(onMessage);
fail: (err) => {
console.error("发送心跳失败", err);
},
});
} }
}, 10000); }, 10000);
} }