| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- /**
- * 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;
|