This commit is contained in:
oneao committed 2025-10-13 17:32:02 +08:00
1 parent a6c5e70f85
commit 2598098876
8 files changed
+646 -45

No files matched your search

@@ -0,0 +1,100 @@
import { ElNotification } from 'element-plus'
import { onScopeDispose, ref } from 'vue'
export function useWebSocket() {
const socket = ref(null)
const isConnected = ref(false)
const listeners = ref(new Set())
let reconnecting = false
let reconnectNotification = null
function connect(url) {
if (isConnected.value)
return
if (socket.value)
disconnect()
const ws = new WebSocket(url)
socket.value = ws
ws.onopen = () => {
isConnected.value = true
reconnecting = false
// 关闭重连提示
if (reconnectNotification) {
reconnectNotification.close()
reconnectNotification = null
}
console.log('WebSocket 已连接')
ElNotification({
title: '成功',
message: 'WebSocket 已连接',
type: 'success',
showClose: false,
duration: 2000,
})
}
ws.onmessage = (event) => {
try {
const message = JSON.parse(event.data)
notifyListeners(message)
}
catch (err) {
console.error('消息解析失败:', err)
notifyListeners({ type: 'ERROR', data: '消息解析失败' })
}
}
ws.onclose = () => scheduleReconnect(url)
ws.onerror = () => scheduleReconnect(url)
}
function disconnect() {
socket.value?.close()
isConnected.value = false
}
function sendMessage(type, data) {
if (isConnected.value && socket.value) {
socket.value.send(JSON.stringify({ type, data }))
}
}
function onMessage(callback) {
listeners.value.add(callback)
return () => listeners.value.delete(callback)
}
function notifyListeners(message) {
listeners.value.forEach(cb => cb(message))
}
function scheduleReconnect(url) {
if (!reconnecting) {
reconnecting = true
reconnectNotification = ElNotification({
title: '提示',
message: 'WebSocket 连接断开,正在重连...',
type: 'warning',
showClose: false,
duration: 0,
})
}
console.log('WebSocket 即将重连...')
setTimeout(() => {
connect(url)
}, 3000) // 固定延迟重连,可按需改
}
onScopeDispose(() => disconnect())
return {
isConnected,
connect,
disconnect,
sendMessage,
onMessage,
}
}