/** * AI问答WebSocket工具函数 */ // AI WebSocket配置 const AI_WS_CONFIG = { baseURL: 'ws://116.62.47.88:5003', timeout: 30000, // 30秒超时 reconnectInterval: 3000, // 重连间隔 maxReconnectAttempts: 3 // 最大重连次数 }; class AIWebSocket { constructor() { this.ws = null; this.url = ''; this.connected = false; this.connecting = false; this.reconnectCount = 0; this.lockReconnect = false; this.messageCallback = null; this.errorCallback = null; this.closeCallback = null; this.reconnectTimer = null; this.heartbeatTimer = null; // 最近一次连接的参数,用于必要时重连 this.lastQuestion = ''; this.lastOnMessage = null; this.lastOnError = null; // 是否允许自动重连(默认不重连,避免重复消息) this.shouldReconnect = false; } /** * 连接WebSocket * @param {string} question - 用户问题 * @param {Function} onMessage - 消息回调函数 * @param {Function} onError - 错误回调函数 */ connect(question, onMessage, onError, onClose) { if (this.connecting || this.connected) { console.log('WebSocket已连接或正在连接中'); return; } // 记录本次连接参数 this.messageCallback = onMessage; this.errorCallback = onError; this.lastQuestion = question; this.lastOnMessage = onMessage; this.lastOnError = onError; this.closeCallback = onClose; // 默认不自动重连,除非调用方显式开启 this.shouldReconnect = false; this.url = `${AI_WS_CONFIG.baseURL}/ws`; try { this.connecting = true; // 创建WebSocket连接 this.ws = uni.connectSocket({ url: this.url, success: (data) => { console.log('AI WebSocket连接创建成功'); }, fail: (error) => { console.error('AI WebSocket连接创建失败:', error); this.handleError('连接创建失败'); } }); // 监听连接打开 this.ws.onOpen((res) => { console.log('AI WebSocket连接已打开'); this.connecting = false; this.connected = true; this.reconnectCount = 0; // 发送问题 this.sendQuestion(question); // 开始心跳检测 this.startHeartbeat(); }); // 监听消息 this.ws.onMessage((res) => { console.log('AI WebSocket收到消息:', res.data); try { const data = JSON.parse(res.data); if (this.messageCallback) { this.messageCallback(data); } } catch (error) { console.error('解析WebSocket消息失败:', error); } }); // 监听错误 this.ws.onError((res) => { console.error('AI WebSocket连接错误:', res); this.handleError('连接错误'); }); // 监听连接关闭 this.ws.onClose((res) => { console.log('AI WebSocket连接已关闭'); this.connected = false; this.connecting = false; this.ws = null; // 停止心跳 this.stopHeartbeat(); // 通知外部关闭事件 if (this.closeCallback) { try { this.closeCallback(res); } catch (e) { console.error('关闭回调执行失败', e); } } // 仅在允许时才尝试重连 if (this.shouldReconnect) { this.reconnect(); } }); } catch (error) { console.error('创建AI WebSocket失败:', error); this.handleError('创建连接失败'); } } /** * 发送问题 * @param {string} question - 用户问题 */ sendQuestion(question) { if (!this.connected || !this.ws) { console.error('WebSocket未连接,无法发送问题'); return; } const message = { question: question }; this.ws.send({ data: JSON.stringify(message), success: () => { console.log('问题发送成功'); }, fail: (error) => { console.error('问题发送失败:', error); this.handleError('发送问题失败'); } }); } /** * 开始心跳检测 */ startHeartbeat() { this.heartbeatTimer = setInterval(() => { if (this.connected && this.ws) { this.ws.send({ data: JSON.stringify({ type: 'ping' }), fail: (error) => { console.error('心跳发送失败:', error); this.reconnect(); } }); } }, 10000); // 每10秒发送一次心跳 } /** * 停止心跳检测 */ stopHeartbeat() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; } } /** * 重连 */ reconnect() { if (this.lockReconnect || this.reconnectCount >= AI_WS_CONFIG.maxReconnectAttempts) { console.log('达到最大重连次数或重连被锁定'); return; } this.lockReconnect = true; this.reconnectCount++; console.log(`尝试重连 (${this.reconnectCount}/${AI_WS_CONFIG.maxReconnectAttempts})`); this.reconnectTimer = setTimeout(() => { this.lockReconnect = false; if (!this.connected) { // 使用最近一次的参数重连 this.connect(this.lastQuestion, this.lastOnMessage, this.lastOnError); } }, AI_WS_CONFIG.reconnectInterval); } /** * 处理错误 * @param {string} error - 错误信息 */ handleError(error) { console.error('AI WebSocket错误:', error); if (this.errorCallback) { this.errorCallback(error); } } /** * 关闭连接 */ close() { console.log('关闭AI WebSocket连接'); // 停止重连 if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); this.reconnectTimer = null; } // 主动关闭时不再重连 this.shouldReconnect = false; // 停止心跳 this.stopHeartbeat(); // 关闭WebSocket if (this.ws && this.connected) { this.ws.close(); } // 重置状态 this.connected = false; this.connecting = false; this.ws = null; this.lockReconnect = false; this.reconnectCount = 0; this.messageCallback = null; this.errorCallback = null; } /** * 启用或禁用自动重连 * @param {boolean} enable 是否启用 */ setAutoReconnect(enable) { this.shouldReconnect = !!enable; } /** * 检查连接状态 * @returns {boolean} 是否已连接 */ isConnected() { return this.connected; } } // 创建单例实例 const aiWebSocket = new AIWebSocket(); export default aiWebSocket;