feat(websocket): 实现 WebSocket通信功能
- 新增 useWebSocket 组合式函数,用于在组件中使用 WebSocket - 添加 WebSocket 插件,提供全局 WebSocket 实例和相关方法 - 实现了连接、重连、发送消息、关闭连接等功能 - 通过自定义事件实现消息广播,供组件监听
This commit is contained in:
parent
e2b5e6bcbf
commit
65f8d2d1e9
21
app/composables/useWebSocket.ts
Normal file
21
app/composables/useWebSocket.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export function useWebSocket() {
|
||||
const { $ws } = useNuxtApp()
|
||||
const messages = ref<any[]>([])
|
||||
|
||||
// 监听消息
|
||||
const onMessage = (callback: (data: any) => void) => {
|
||||
const handler = (event: CustomEvent) => callback(event.detail)
|
||||
window.addEventListener('ws-message', handler as EventListener)
|
||||
|
||||
// 返回清理函数
|
||||
return () => {
|
||||
window.removeEventListener('ws-message', handler as EventListener)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ws: $ws,
|
||||
messages,
|
||||
onMessage
|
||||
}
|
||||
}
|
86
app/plugins/websocket.ts
Normal file
86
app/plugins/websocket.ts
Normal file
@ -0,0 +1,86 @@
|
||||
export default defineNuxtPlugin(() => {
|
||||
const config = useRuntimeConfig()
|
||||
const ws = reactive({
|
||||
instance: null as WebSocket | null,
|
||||
isConnected: false,
|
||||
|
||||
// 修改 connect 方法接收路径和数据对象
|
||||
connect(path: string, data?: Record<string, any>) {
|
||||
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||
this.instance.close()
|
||||
}
|
||||
|
||||
// 构建查询字符串
|
||||
const queryString = data
|
||||
? '?' + Object.entries(data)
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
.join('&')
|
||||
: ''
|
||||
|
||||
// 构建完整的 WebSocket URL
|
||||
const wsUrl = `${config.public.NUXT_PUBLIC_SOCKET_URL}${path}${queryString}`
|
||||
this.instance = new WebSocket(wsUrl)
|
||||
|
||||
this.instance.onopen = () => {
|
||||
this.isConnected = true
|
||||
console.log('WebSocket 已连接')
|
||||
}
|
||||
|
||||
this.instance.onclose = () => {
|
||||
this.isConnected = false
|
||||
console.log('WebSocket 已断开')
|
||||
/* this.reconnect(path, data)*/
|
||||
}
|
||||
|
||||
this.instance.onerror = (error) => {
|
||||
console.error('WebSocket 错误:', error)
|
||||
}
|
||||
|
||||
this.instance.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data)
|
||||
this.handleMessage(data)
|
||||
} catch (error) {
|
||||
console.error('消息解析错误:', error)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 更新重连方法以支持数据对象
|
||||
reconnect(path: string, data?: Record<string, any>) {
|
||||
setTimeout(() => {
|
||||
console.log('尝试重新连接...')
|
||||
this.connect(path, data)
|
||||
}, 3000)
|
||||
},
|
||||
|
||||
// 发送消息
|
||||
send(data: any) {
|
||||
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||
this.instance.send(JSON.stringify(data))
|
||||
} else {
|
||||
console.warn('WebSocket 未连接,无法发送消息')
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭连接
|
||||
disconnect() {
|
||||
if (this.instance) {
|
||||
this.instance.close()
|
||||
this.instance = null
|
||||
}
|
||||
},
|
||||
|
||||
// 消息处理
|
||||
handleMessage(data: any) {
|
||||
// 触发自定义事件,让组件可以监听
|
||||
window.dispatchEvent(new CustomEvent('ws-message', { detail: data }))
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
provide: {
|
||||
ws
|
||||
}
|
||||
}
|
||||
})
|
9139
pnpm-lock.yaml
Normal file
9139
pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user