wsUtil.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. export default class WSClient {
  2. constructor(options) {
  3. // 基础配置
  4. this.url = options.url;
  5. this.timeout = options.timeout || 60000;
  6. this.headers = {
  7. ...options.headers
  8. };
  9. // 状态管理
  10. this.ws = null;
  11. this.isConnected = false;
  12. this.fullThinking = '';
  13. this.fullAnswer = '';
  14. this.timeoutId = null;
  15. // 事件回调
  16. this.callbacks = {
  17. open: [],
  18. close: [],
  19. error: [],
  20. start: [],
  21. status: [],
  22. thinking: [],
  23. answer: [],
  24. finish: []
  25. };
  26. }
  27. // 注册事件监听
  28. on(event, callback) {
  29. if (this.callbacks[event]) {
  30. this.callbacks[event].push(callback);
  31. } else {
  32. console.warn(`未知事件类型: ${event}`);
  33. }
  34. }
  35. // 触发事件
  36. emit(event, data) {
  37. if (this.callbacks[event]) {
  38. this.callbacks[event].forEach(callback => {
  39. try {
  40. callback({ ...data, timestamp: Date.now() });
  41. } catch (e) {
  42. console.error(`事件${event}回调错误:`, e);
  43. }
  44. });
  45. }
  46. }
  47. // 建立连接
  48. open(data) {
  49. // 关闭现有连接
  50. this.close();
  51. // 重置状态
  52. this.fullThinking = '';
  53. this.fullAnswer = '';
  54. try {
  55. // 创建 WebSocket 连接
  56. this.ws = uni.connectSocket({
  57. url: this.url,
  58. header: this.headers,
  59. complete: () => {
  60. // 连接完成回调
  61. }
  62. });
  63. // uni.connectSocket 是异步的,需要在 success 回调中处理
  64. this.ws.onOpen((res) => {
  65. clearTimeout(this.timeoutId);
  66. this.isConnected = true;
  67. this.emit('open', { res });
  68. // 连接建立后发送数据
  69. // if (data) {
  70. // this.send(data);
  71. // }
  72. });
  73. this.ws.onMessage((res) => {
  74. console.log('接收到数据:', res,);
  75. let segmentText = '';
  76. try {
  77. // 先检查数据是否为字符串
  78. if (typeof res.data === 'string' && res.data.trim().startsWith('{') || res.data.trim().startsWith('[')) {
  79. // 只有看起来像JSON的字符串才尝试解析
  80. const parsedData = JSON.parse(res.data);
  81. segmentText = parsedData.text || parsedData.message || JSON.stringify(parsedData);
  82. } else {
  83. // 直接使用原始数据
  84. segmentText = res.data;
  85. }
  86. } catch (e) {
  87. console.error('JSON解析错误:', e, '原始数据:', res.data);
  88. // 解析失败,直接使用原始数据
  89. segmentText = res.data;
  90. }
  91. console.log('处理后的文本段:', segmentText);
  92. this.emit('answer', {
  93. segment: segmentText,
  94. });
  95. });
  96. this.ws.onError((error) => {
  97. clearTimeout(this.timeoutId);
  98. this.emit('error', { type: 'ws.onError', message: error.errMsg || '连接错误' });
  99. });
  100. this.ws.onClose((res) => {
  101. console.log('ws连接已关闭:', res);
  102. this.emit('close', {
  103. type: 'ws.onClose',
  104. reason: res.reason || '连接关闭',
  105. code: res.code
  106. });
  107. clearTimeout(this.timeoutId);
  108. this.isConnected = false;
  109. });
  110. // 设置连接超时
  111. // this.timeoutId = setTimeout(() => {
  112. // if (!this.isConnected) {
  113. // this.emit('error', { type: 'timeout', message: '连接超时' });
  114. // this.close();
  115. // }
  116. // }, this.timeout);
  117. } catch (error) {
  118. clearTimeout(this.timeoutId);
  119. this.emit('error', { type: 'init-try-catch', message: error.message || '初始化错误' });
  120. }
  121. }
  122. // 发送数据
  123. send(data) {
  124. console.log('ws发送数据:', data);
  125. if (this.ws && this.isConnected) {
  126. this.ws.send({
  127. data: JSON.stringify(data),
  128. success: (res) => {
  129. // 发送成功
  130. console.log('ws发送成功:', res);
  131. },
  132. fail: (err) => {
  133. this.emit('error', { type: 'send', message: '发送失败: ' + err.errMsg });
  134. }
  135. });
  136. } else {
  137. this.emit('error', { type: 'send', message: '连接未建立' });
  138. }
  139. }
  140. // 关闭连接
  141. close(reason) {
  142. if (this.ws) {
  143. this.ws.close({
  144. success: () => {
  145. // 关闭成功
  146. },
  147. fail: (err) => {
  148. console.error('关闭连接失败:', err);
  149. }
  150. });
  151. this.ws = null;
  152. }
  153. this.isConnected = false;
  154. clearTimeout(this.timeoutId);
  155. if (reason) {
  156. this.emit('close', { reason });
  157. }
  158. }
  159. }