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

View File

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

View File

@@ -1,16 +1,8 @@
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 连接
*/
@@ -20,9 +12,8 @@ function createWebSocket(token, onMessage) {
url,
success: () => {
console.log("websocket 连接成功");
reconnectCount = 0; // 重置重连次数
// 启动心跳
startHeartbeat();
startHeartbeat(onMessage);
},
fail: () => {
reconnect(onMessage);
@@ -32,6 +23,7 @@ function createWebSocket(token, onMessage) {
// 接收消息
uni.onSocketMessage((res) => {
const data = JSON.parse(res.data);
// console.log(res);
if (data.event === "pong" || !data.data.updates) return;
if (onMessage) onMessage(data.data.updates);
const msg = data.data.updates[0];
@@ -66,7 +58,7 @@ function createWebSocket(token, onMessage) {
// 错误处理
uni.onSocketError((err) => {
console.error("WebSocket 错误", err);
reconnect(token, onMessage);
reconnect(onMessage);
});
uni.onSocketClose((result) => {
@@ -80,48 +72,58 @@ function createWebSocket(token, onMessage) {
* 重连机制
*/
function reconnect(onMessage) {
if (reconnectCount >= RECONNECT_CONFIG.MAX_COUNT) return;
reconnectTimer && clearTimeout(reconnectTimer);
closeWebSocket(); // 确保关闭旧连接
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);
}, 1000);
}
function closeWebSocket() {
if (socket) {
// 清理重连定时器
reconnectCount = 0;
reconnectTimer && clearTimeout(reconnectTimer);
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(); // 防止重复启动
heartbeatInterval = setInterval(() => {
if (socket) {
uni.sendSocketMessage({
data: JSON.stringify({ event: "ping", data: {} }),
fail: (err) => {
console.error("发送心跳失败", err);
},
});
if (socket && socket.readyState === 1) {
// 检查连接状态
sendHeartbeat(onMessage);
}
}, 10000);
}