topfans/frontend/utils/socket/AiChatSocket.js
2026-05-28 12:00:19 +08:00

187 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SocketManager from './SocketManager'
/**
* AI Chat WebSocket 连接
* 继承自 SocketManager添加 AI Chat 特定的业务逻辑
*/
class AiChatSocket extends SocketManager {
constructor() {
super({
serviceName: 'AiChat',
baseUrl: 'ws://gateway:8080',
path: '/ws/ai-chat',
reconnectInterval: 3000,
heartbeatInterval: 30000,
maxReconnectAttempts: 5
})
// AI Chat 特定回调
this.onMessageCallback = null
this.onHistoryCallback = null
this.onPersonasCallback = null
this.onErrorCallback = null
this.onConnectCallback = null
// 注册 AI Chat 特定的消息处理器
this._registerAiChatHandlers()
}
setClosing(val) {
this.isClosing = val
}
_registerAiChatHandlers() {
// 流式消息
this.registerHandler('message', (data) => {
if (this.onMessageCallback) {
this.onMessageCallback(data)
}
})
// 历史消息响应
this.registerHandler('history_response', (data) => {
if (this.onHistoryCallback) {
this.onHistoryCallback(data)
}
})
// 人设列表响应
this.registerHandler('personas_response', (data) => {
if (this.onPersonasCallback) {
this.onPersonasCallback(data)
}
})
}
/**
* 连接到 AI Chat 服务
*/
async connect(token) {
await super.connect(token, '/ws/ai-chat')
}
/**
* 发送消息
*/
sendMessage(message, sessionId, personaId = '') {
return this.send({
action: 'send_message',
session_id: sessionId,
message: message,
persona_id: personaId
})
}
/**
* 获取历史记录
*/
getHistory(sessionId, limit = 20) {
return this.send({
action: 'get_history',
session_id: sessionId,
limit: limit
})
}
/**
* 初始化会话
*/
initSession(sessionId) {
return this.send({
action: 'init_session',
session_id: sessionId
})
}
/**
* 获取人设列表
*/
getPersonas() {
return this.send({
action: 'get_personas'
})
}
/**
* 设置消息回调
*/
setOnMessageCallback(callback) {
this.onMessageCallback = callback
this.off('message', this._messageHandler)
this._messageHandler = (data) => {
if (this.onMessageCallback) this.onMessageCallback(data)
}
this.on('message', this._messageHandler)
}
/**
* 设置历史记录回调
*/
setOnHistoryCallback(callback) {
this.onHistoryCallback = callback
}
/**
* 设置人设列表回调
*/
setOnPersonasCallback(callback) {
this.onPersonasCallback = callback
}
/**
* 设置错误回调
*/
setOnErrorCallback(callback) {
this.onErrorCallback = callback
this.off('error', this._errorHandler)
this._errorHandler = (data) => {
if (callback) callback(data)
}
this.on('error', this._errorHandler)
}
/**
* 设置连接成功回调
*/
setOnConnectCallback(callback) {
// 移除旧的 connect listener防止重复注册
if (this._connectHandler) {
this.off('connect', this._connectHandler)
}
this.onConnectCallback = callback
this._connectHandler = () => {
if (callback) callback()
}
this.on('connect', this._connectHandler)
}
}
// 单例模式
let aiChatInstance = null
let closing = false // 标记是否主动关闭
export function getAiChatSocket() {
if (!aiChatInstance) {
aiChatInstance = new AiChatSocket()
}
return aiChatInstance
}
export function closeAiChatSocket() {
if (aiChatInstance) {
closing = true
aiChatInstance.close()
// 不再设为 null保持实例以防止旧定时器创建新连接
// 下次 getAiChatSocket() 继续使用同一实例
}
}
export function isAiChatClosing() {
return closing
}
export function resetAiChatClosing() {
closing = false
}
export default AiChatSocket