websocket逻辑优化
This commit is contained in:
18
src/App.vue
18
src/App.vue
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
// 如果发送失败,说明连接已断开,需要重新连接
|
// 如果发送失败,说明连接已断开,需要重新连接
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user