优化WebSocket使用指南和消息订阅逻辑,调整代码格式以提升可读性,确保一致性。新增调试信息记录功能,增强事件系统的类型安全性,支持多种消息和会话事件的订阅与发布。

This commit is contained in:
乘风
2026-01-14 15:34:44 +08:00
parent 67cb6c02ed
commit 0d6e1edd91
2 changed files with 64 additions and 59 deletions

View File

@@ -36,7 +36,7 @@ const { sendCommand } = useWebSocket()
sendCommand('CmdSendTextMsg', {
content: '你好',
targetId: 123,
targetType: 'friend'
targetType: 'friend',
})
```
@@ -51,16 +51,16 @@ import { useMessageSubscription } from '@/composables/business/wechat/useMessage
export const useMessageStore = defineStore('message', () => {
const messages = ref<Message[]>([])
// 订阅消息(只需要写一次)
const { onNewMessage } = useMessageSubscription()
onNewMessage((message) => {
messages.value.push(message)
})
return {
messages
messages,
}
})
```
@@ -75,11 +75,11 @@ export const useMessageStore = defineStore('message', () => {
```typescript
// 可用的订阅方法
onNewMessage // 新消息
onMessageUpdate // 消息更新
onMessageRecall // 消息撤回
onSessionUpdate // 会话更新
onAccountStatus // 账号状态
onNewMessage // 新消息
onMessageUpdate // 消息更新
onMessageRecall // 消息撤回
onSessionUpdate // 会话更新
onAccountStatus // 账号状态
onSystemNotification // 系统通知
```
@@ -141,6 +141,7 @@ onNewMessage((msg) => {
```
**好处:**
- 组件不需要导入 Store
- Store 可以随时更换,不影响组件
- 测试更简单
@@ -155,8 +156,12 @@ onNewMessage((msg) => {
// 1. 在 Store 中统一订阅
// stores/modules/wechat/useMessageStore.ts
setupMessageSubscription({
onNewMessage: (msg) => { /* 处理 */ },
onMessageUpdate: ({ id, changes }) => { /* 处理 */ }
onNewMessage: (msg) => {
/* 处理 */
},
onMessageUpdate: ({ id, changes }) => {
/* 处理 */
},
})
// 2. 组件中只读取 Store 数据

View File

@@ -1,11 +1,11 @@
/**
* WebSocket 消息订阅中心(发布订阅模式)
*
*
* 核心职责:
* - 解耦消息发送方WebSocket和接收方组件/Store
* - 支持多个订阅者
* - 提供类型安全的事件系统
*
*
* 使用场景:
* 1. 组件订阅:实时更新 UI
* 2. Store 订阅:更新全局状态
@@ -20,31 +20,31 @@ import type { Message } from '@/types/wechat'
type MessageEvents = {
// 新消息
'message:new': Message
// 消息更新
'message:update': {
id: number | string
changes: Partial<Message>
}
// 消息撤回
'message:recall': {
messageId: number
sessionId: number
}
// 会话更新
'session:update': {
sessionId: number
changes: any
}
// 账号状态
'account:status': {
accountId: number
isOnline: boolean
}
// 系统通知
'system:notification': {
type: string
@@ -62,17 +62,17 @@ const isDev = import.meta.env.DEV
function logSubscription(event: keyof MessageEvents, action: 'subscribe' | 'unsubscribe') {
if (!isDev) return
const count = subscriptionCount.get(event) || 0
const newCount = action === 'subscribe' ? count + 1 : Math.max(0, count - 1)
subscriptionCount.set(event, newCount)
console.log(`[MessageSubscription] ${action}: ${event}, 当前订阅数: ${newCount}`)
}
function logEmit(event: keyof MessageEvents, data: any) {
if (!isDev) return
const count = subscriptionCount.get(event) || 0
console.log(`[MessageSubscription] emit: ${event}, 订阅者数: ${count}`, {
preview: JSON.stringify(data).substring(0, 100) + '...',
@@ -87,7 +87,7 @@ function logEmit(event: keyof MessageEvents, data: any) {
function getEmitter(): Emitter<MessageEvents> {
if (!eventEmitter) {
eventEmitter = mitt<MessageEvents>()
// 开发环境:显示订阅信息
if (isDev) {
console.log('[MessageSubscription] 事件中心已初始化')
@@ -98,40 +98,40 @@ function getEmitter(): Emitter<MessageEvents> {
/**
* 消息订阅 Hook
*
*
* @example
* ```typescript
* // 在组件中使用
* const { onNewMessage, emitNewMessage } = useMessageSubscription()
*
*
* // 订阅新消息
* onNewMessage((message) => {
* console.log('收到新消息:', message)
* })
*
*
* // 发布新消息(通常由 WebSocket 调用)
* emitNewMessage(message)
* ```
*/
export function useMessageSubscription() {
const emitter = getEmitter()
// ==================== 订阅方法(组件/Store 使用)====================
/**
* 订阅新消息
*/
const onNewMessage = (handler: (message: Message) => void) => {
logSubscription('message:new', 'subscribe')
emitter.on('message:new', handler)
// 返回取消订阅函数
return () => {
logSubscription('message:new', 'unsubscribe')
emitter.off('message:new', handler)
}
}
/**
* 订阅消息更新
*/
@@ -140,67 +140,67 @@ export function useMessageSubscription() {
) => {
logSubscription('message:update', 'subscribe')
emitter.on('message:update', handler)
return () => {
logSubscription('message:update', 'unsubscribe')
emitter.off('message:update', handler)
}
}
/**
* 订阅消息撤回
*/
const onMessageRecall = (handler: (data: { messageId: number; sessionId: number }) => void) => {
logSubscription('message:recall', 'subscribe')
emitter.on('message:recall', handler)
return () => {
logSubscription('message:recall', 'unsubscribe')
emitter.off('message:recall', handler)
}
}
/**
* 订阅会话更新
*/
const onSessionUpdate = (handler: (data: { sessionId: number; changes: any }) => void) => {
logSubscription('session:update', 'subscribe')
emitter.on('session:update', handler)
return () => {
logSubscription('session:update', 'unsubscribe')
emitter.off('session:update', handler)
}
}
/**
* 订阅账号状态
*/
const onAccountStatus = (handler: (data: { accountId: number; isOnline: boolean }) => void) => {
logSubscription('account:status', 'subscribe')
emitter.on('account:status', handler)
return () => {
logSubscription('account:status', 'unsubscribe')
emitter.off('account:status', handler)
}
}
/**
* 订阅系统通知
*/
const onSystemNotification = (handler: (data: { type: string; content: string }) => void) => {
logSubscription('system:notification', 'subscribe')
emitter.on('system:notification', handler)
return () => {
logSubscription('system:notification', 'unsubscribe')
emitter.off('system:notification', handler)
}
}
// ==================== 发布方法WebSocket 使用)====================
/**
* 发布新消息
*/
@@ -208,7 +208,7 @@ export function useMessageSubscription() {
logEmit('message:new', message)
emitter.emit('message:new', message)
}
/**
* 发布消息更新
*/
@@ -216,7 +216,7 @@ export function useMessageSubscription() {
logEmit('message:update', { id, changes })
emitter.emit('message:update', { id, changes })
}
/**
* 发布消息撤回
*/
@@ -224,7 +224,7 @@ export function useMessageSubscription() {
logEmit('message:recall', { messageId, sessionId })
emitter.emit('message:recall', { messageId, sessionId })
}
/**
* 发布会话更新
*/
@@ -232,7 +232,7 @@ export function useMessageSubscription() {
logEmit('session:update', { sessionId, changes })
emitter.emit('session:update', { sessionId, changes })
}
/**
* 发布账号状态
*/
@@ -240,7 +240,7 @@ export function useMessageSubscription() {
logEmit('account:status', { accountId, isOnline })
emitter.emit('account:status', { accountId, isOnline })
}
/**
* 发布系统通知
*/
@@ -248,9 +248,9 @@ export function useMessageSubscription() {
logEmit('system:notification', { type, content })
emitter.emit('system:notification', { type, content })
}
// ==================== 工具方法 ====================
/**
* 清除所有订阅(用于测试)
*/
@@ -259,14 +259,14 @@ export function useMessageSubscription() {
subscriptionCount.clear()
console.log('[MessageSubscription] 已清除所有订阅')
}
/**
* 获取订阅统计(用于调试)
*/
const getStats = () => {
return Object.fromEntries(subscriptionCount)
}
return {
// 订阅
onNewMessage,
@@ -275,7 +275,7 @@ export function useMessageSubscription() {
onSessionUpdate,
onAccountStatus,
onSystemNotification,
// 发布
emitNewMessage,
emitMessageUpdate,
@@ -283,7 +283,7 @@ export function useMessageSubscription() {
emitSessionUpdate,
emitAccountStatus,
emitSystemNotification,
// 工具
clearAll,
getStats,
@@ -292,15 +292,15 @@ export function useMessageSubscription() {
/**
* 全局单例:在 Store 中统一订阅
*
*
* @example
* ```typescript
* // stores/modules/wechat/useMessageStore.ts
* import { setupMessageSubscription } from '@/composables/business/wechat/useMessageSubscription'
*
*
* export const useMessageStore = defineStore('message', () => {
* const messages = ref<Message[]>([])
*
*
* // 设置订阅
* setupMessageSubscription({
* onNewMessage: (msg) => {
@@ -310,7 +310,7 @@ export function useMessageSubscription() {
* // 更新消息
* }
* })
*
*
* return { messages }
* })
* ```
@@ -324,10 +324,10 @@ export function setupMessageSubscription(handlers: {
onSystemNotification?: (data: { type: string; content: string }) => void
}) {
const subscription = useMessageSubscription()
// 自动设置所有订阅
const unsubscribers: (() => void)[] = []
if (handlers.onNewMessage) {
unsubscribers.push(subscription.onNewMessage(handlers.onNewMessage))
}
@@ -346,7 +346,7 @@ export function setupMessageSubscription(handlers: {
if (handlers.onSystemNotification) {
unsubscribers.push(subscription.onSystemNotification(handlers.onSystemNotification))
}
// 返回统一的清理函数
return () => {
unsubscribers.forEach(unsub => unsub())