文章目录
-
- 一、添加存活时间控制的方案
- [💡 **推荐实践**](#💡 推荐实践)
当前逻辑没有设置 WebSocket 的存活时间。让我分析一下各个配置的作用:
配置的功能:
- ✅ 心跳机制:每10秒发送一次 "ping"
- ✅ 自动重连:断开后重试3次,每次间隔5秒
- ✅ 基础事件处理:消息接收、断开连接处理
- ✅ 添加存活机制:一定条件下主动断开连接
一、添加存活时间控制的方案
方案1:设置固定存活时间
javascript
const getWsUrl = async () => {
const res = await getWebsocketUrl()
wsUrl.value = res + "alarm/send"
// 设置 WebSocket 最大存活时间(例如30分钟)
const MAX_LIFETIME = 30 * 60 * 1000 // 30分钟
webSocket.value = useWebSocket(wsUrl, {
onMessage: (ws, { data }) => {
if (!_.isEmpty(data) && data !== undefined && data !== "undefined") {
let datas = JSON.parse(data) || {}
if (datas.messageType == "TOPU_ALARM") {
settingStore.tupuWarnList = JSON.parse(datas.messageContext)
} else {
getNotification(datas)
}
}
},
onDisconnected: () => {
console.log("websocket断开链接")
// 清除存活定时器
if (lifetimeTimer) {
clearTimeout(lifetimeTimer)
}
},
autoReconnect: {
retries: 3,
delay: 5000,
onFailed() {
ElMessage.error("websocket链接失败")
// 清除存活定时器
if (lifetimeTimer) {
clearTimeout(lifetimeTimer)
}
}
},
heartbeat: {
message: "ping",
interval: 10000,
pongTimeout: 1000
}
})
webSocket.value.send(JSON.stringify({ userId: userStore?.userInfo?.id }))
// 设置存活定时器,在指定时间后主动断开
const lifetimeTimer = setTimeout(() => {
if (webSocket.value && webSocket.value.close) {
console.log('WebSocket 已达到最大存活时间,主动断开')
webSocket.value.close()
}
}, MAX_LIFETIME)
}
onMounted(() => {
// 触发ws
etWsUrl()
})
方案2:基于业务逻辑的存活控制
javascript
const getWsUrl = async () => {
const res = await getWebsocketUrl()
wsUrl.value = res + "alarm/send"
// 根据业务需求设置条件
let shouldKeepAlive = true
webSocket.value = useWebSocket(wsUrl, {
onMessage: (ws, { data }) => {
if (!_.isEmpty(data) && data !== undefined && data !== "undefined") {
let datas = JSON.parse(data) || {}
// 根据特定消息决定是否保持连接
if (datas.messageType === "CLOSE_CONNECTION") {
shouldKeepAlive = false
webSocket.value?.close()
return
}
if (datas.messageType == "TOPU_ALARM") {
settingStore.tupuWarnList = JSON.parse(datas.messageContext)
} else {
getNotification(datas)
}
}
},
// ... 其他配置不变
})
webSocket.value.send(JSON.stringify({ userId: userStore?.userInfo?.id }))
}
onMounted(() => {
// 触发ws
etWsUrl()
})
方案3:页面隐藏时断开(推荐)
javascript
import { onBeforeUnmount } from 'vue'
const getWsUrl = async () => {
const res = await getWebsocketUrl()
wsUrl.value = res + "alarm/send"
webSocket.value = useWebSocket(wsUrl, {
// ... 你现有的配置
})
webSocket.value.send(JSON.stringify({ userId: userStore?.userInfo?.id }))
// 页面隐藏时断开 WebSocket
const handleVisibilityChange = () => {
if (document.hidden && webSocket.value) {
console.log('页面隐藏,断开 WebSocket')
webSocket.value.close()
}
}
document.addEventListener('visibilitychange', handleVisibilityChange)
// 组件卸载时清理
onBeforeUnmount(() => {
document.removeEventListener('visibilitychange', handleVisibilityChange)
if (webSocket.value) {
webSocket.value.close()
}
})
}
onMounted(() => {
// 触发ws
etWsUrl()
})
💡 推荐实践
根据您的业务场景,建议:
- 如果不需要长期连接:使用方案1,设置合理的存活时间(如30分钟)
- 如果需要优化性能:使用方案3,在页面不可见时断开
- 如果依赖服务端控制:保持现状,让服务端决定连接生命周期
如果没有特殊需求,保持现状即可。WebSocket 连接通常设计为长期保持,由服务端或网络条件决定断开时机。