封装的重点是响应式状态管理、自动重连、心跳检测、消息队列、生命周期管理和易用性。通过Composition API将这些功能模块化,方便在Vue3组件中复用。
1、在 Vue3 中对 WebSocket 进行封装时,可以利用 Composition API 实现更优雅的封装。下面是一个功能完善且支持自动重连、心跳检测的 WebSocket 封装方案:
import { ref, reactive, onUnmounted } from 'vue'
interface WebSocketOptions {
// 自动重连次数(默认 3 次)
reconnectLimit?: number
// 重连间隔(默认 3000ms)
reconnectInterval?: number
// 心跳间隔(默认 30000ms)
heartInterval?: number
// 心跳消息(默认 ping)
heartMessage?: string
// 是否自动连接(默认 true)
autoConnect?: boolean
// 协议字符串或字符串数组
protocols?: string | string[]
}
export function useWebSocket(url: string, options: WebSocketOptions = {}) {
const {
reconnectLimit = 3,
reconnectInterval = 3000,
heartInterval = 30000,
heartMessage = 'ping',
autoConnect = true,
protocols = []
} = options
// 响应式状态
const ws = ref<WebSocket | null>(null)
const isConnected = ref(false)
const messageQueue = reactive<any[]>([])
const reconnectCount = ref(0)
const timer = ref<number>()
const heartTimer = ref<number>()
// 事件处理器
const handlers = reactive<{
message: ((event: MessageEvent) => void)[]
open: ((event: Event) => void)[]
close: ((event: CloseEvent) => void)[]
error: ((event: Event) => void)[]
}>({
message: [],
open: [],
close: [],
error: []
})
// 心跳检测
const heartCheck = () => {
heartTimer.value = window.setInterval(() => {
send(heartMessage)
}, heartInterval)
}
// 清除心跳
const clearHeartCheck = () => {
heartTimer.value && clearInterval(heartTimer.value)
}
// 发送消息
const send = (data: string | ArrayBuffer | Blob) => {
if (isConnected.value && ws.value) {
ws.value.send(data)
} else {
messageQueue.push(data)
}
}
// 处理队列消息
const processMessageQueue = () => {
while (messageQueue.length > 0 && ws.value) {
const message = messageQueue.shift()
ws.value.send(message)
}
}
// 关闭连接
const close = () => {
ws.value?.close()
}
// 创建连接
const connect = () => {
ws.value = new WebSocket(url, protocols)
ws.value.onopen = (event) => {
isConnected.value = true
reconnectCount.value = 0
processMessageQueue()
heartCheck()
handlers.open.forEach(handler => handler(event))
}
ws.value.onmessage = (event) => {
handlers.message.forEach(handler => handler(event))
}
ws.value.onclose = (event) => {
isConnected.value = false
clearHeartCheck()
handlers.close.forEach(handler => handler(event))
if (reconnectCount.value < reconnectLimit) {
timer.value = window.setTimeout(() => {
reconnectCount.value++
connect()
}, reconnectInterval)
}
}
ws.value.onerror = (event) => {
isConnected.value = false
clearHeartCheck()
handlers.error.forEach(handler => handler(event))
ws.value?.close()
}
}
// 自动连接
if (autoConnect) {
connect()
}
// 组件卸载时清理
onUnmounted(() => {
close()
timer.value && clearTimeout(timer.value)
clearHeartCheck()
})
return {
ws,
isConnected,
send,
close,
connect,
messageQueue,
onMessage: (handler: (event: MessageEvent) => void) => {
handlers.message.push(handler)
},
onOpen: (handler: (event: Event) => void) => {
handlers.open.push(handler)
},
onClose: (handler: (event: CloseEvent) => void) => {
handlers.close.push(handler)
},
onError: (handler: (event: Event) => void) => {
handlers.error.push(handler)
}
}
}
2、使用示例
<script setup lang="ts">
import { useWebSocket } from './useWebSocket'
const {
isConnected,
send,
onMessage,
onOpen,
onClose
} = useWebSocket('wss://echo.websocket.org', {
heartInterval: 15000,
reconnectLimit: 5
})
onOpen(() => {
console.log('连接已建立')
send('Hello Server!')
})
onMessage((event) => {
console.log('收到消息:', event.data)
})
onClose(() => {
console.log('连接已关闭')
})
</script>
<template>
<div>
<p>连接状态: {{ isConnected ? '已连接' : '未连接' }}</p>
<button @click="send('ping')">发送心跳</button>
</div>
</template>
3、功能总结:
主要功能特性
-
自动重连机制
-
当连接意外断开时自动尝试重连
-
可配置最大重连次数和重连间隔
-
重连次数计数器自动重置
-
-
心跳检测
-
定期发送心跳消息保持连接
-
可自定义心跳间隔和消息内容
-
自动清除心跳定时器
-
-
消息队列管理
-
在连接建立前缓存待发送消息
-
连接成功后自动发送队列消息
-
支持字符串、ArrayBuffer 和 Blob 格式
-
-
事件监听
-
提供 open、message、close、error 事件订阅
-
支持多个事件处理器
-
自动清理事件监听
-
-
响应式状态
-
使用 ref 和 reactive 管理连接状态
-
自动更新连接状态(isConnected)
-
消息队列响应式更新
-
-
生命周期管理
-
组件卸载时自动关闭连接
-
自动清理定时器和心跳检测
-
防止内存泄漏
-
-
灵活配置
-
支持自定义协议
-
可配置是否自动连接
-
参数类型严格校验
-
注意事项
-
需要根据业务需求适当调整心跳间隔
-
重连次数不宜设置过大(建议 3-5 次)
-
建议配合 JSON 格式使用消息内容
-
生产环境需要处理 WebSocket 安全策略
-
对于敏感操作建议添加认证机制
-
可扩展添加消息序列化/反序列化逻辑
这个封装方案提供了 WebSocket 的核心功能实现,可以根据具体业务需求进行扩展,例如添加消息类型验证、请求响应匹配、二进制数据处理等功能。