102 lines
3.4 KiB
JavaScript
102 lines
3.4 KiB
JavaScript
import { getAiChatSocket } from './AiChatSocket'
|
||
import { getActivitySocket } from './ActivitySocket'
|
||
|
||
/**
|
||
* 全局 WebSocket 管理器
|
||
* 统一管理多个服务的 WebSocket 连接
|
||
*/
|
||
class GlobalSocketManager {
|
||
constructor() {
|
||
this.sockets = {} // serviceName -> SocketManager
|
||
this.token = null
|
||
this.isAllConnected = false
|
||
this._initialized = false // 防止重复 init 导致监听器累积
|
||
// 保存监听器引用,用于 cleanup
|
||
this._aiChatConnectHandler = null
|
||
this._aiChatErrorHandler = null
|
||
this._activityConnectHandler = null
|
||
this._activityErrorHandler = null
|
||
}
|
||
|
||
/**
|
||
* 初始化所有连接(幂等,重复调用会先清理旧监听器再重连)
|
||
*/
|
||
init(token) {
|
||
this.token = token
|
||
|
||
// 总是先清理旧监听器再注册新的,防止累积。
|
||
// 注意:closeAll() 会清空 this.sockets,所以 cleanup 必须通过单例 getter 获取 socket 引用。
|
||
this._cleanupListeners()
|
||
this._initialized = true
|
||
|
||
this._initAiChat()
|
||
this._initActivity()
|
||
// Future: this._initNotification()
|
||
}
|
||
|
||
async _initAiChat() {
|
||
const aiChat = getAiChatSocket()
|
||
this._aiChatConnectHandler = () => console.log('AI Chat connected')
|
||
this._aiChatErrorHandler = (err) => console.error('AI Chat error:', err)
|
||
aiChat.on('connect', this._aiChatConnectHandler)
|
||
aiChat.on('error', this._aiChatErrorHandler)
|
||
await aiChat.connect(this.token)
|
||
this.sockets['ai_chat'] = aiChat
|
||
}
|
||
|
||
async _initActivity() {
|
||
const activity = getActivitySocket()
|
||
this._activityConnectHandler = () => console.log('Activity socket connected')
|
||
this._activityErrorHandler = (err) => console.error('Activity socket error:', err)
|
||
activity.on('connect', this._activityConnectHandler)
|
||
activity.on('error', this._activityErrorHandler)
|
||
if (this.token) {
|
||
await activity.connect(this.token)
|
||
}
|
||
this.sockets['activity'] = activity
|
||
}
|
||
|
||
/**
|
||
* 清理之前注册的监听器,防止每次 init() 累积。
|
||
* 通过单例 getter 获取 socket 引用(而非 this.sockets),
|
||
* 因为 closeAll() 会清空 this.sockets 但单例仍存活。
|
||
*/
|
||
_cleanupListeners() {
|
||
try {
|
||
const aiChat = getAiChatSocket()
|
||
if (this._aiChatConnectHandler) {
|
||
aiChat.off('connect', this._aiChatConnectHandler)
|
||
aiChat.off('error', this._aiChatErrorHandler)
|
||
}
|
||
} catch (e) { /* singleton not yet created, skip */ }
|
||
|
||
try {
|
||
const activity = getActivitySocket()
|
||
if (this._activityConnectHandler) {
|
||
activity.off('connect', this._activityConnectHandler)
|
||
activity.off('error', this._activityErrorHandler)
|
||
}
|
||
} catch (e) { /* singleton not yet created, skip */ }
|
||
}
|
||
|
||
getSocket(serviceName) {
|
||
return this.sockets[serviceName]
|
||
}
|
||
|
||
closeAll() {
|
||
Object.values(this.sockets).forEach(socket => socket.close())
|
||
this.sockets = {}
|
||
this._initialized = false // 关闭后允许下次 init() 重新注册监听器
|
||
}
|
||
}
|
||
|
||
let globalInstance = null
|
||
|
||
export function getGlobalSocket() {
|
||
if (!globalInstance) {
|
||
globalInstance = new GlobalSocketManager()
|
||
}
|
||
return globalInstance
|
||
}
|
||
|
||
export default GlobalSocketManager |