import config from '@/config' /** * 测量数据 WebSocket(与 l2/socket/index.vue 类似) * 默认订阅 type=track_measure */ export function createMeasureSocket({ type = 'track_measure', onOpen, onClose, onError, onMessage } = {}) { let socket = null let manualClose = false // 保存回调函数的引用,允许清空 let callbacks = { onOpen, onClose, onError, onMessage } const wsBase = (config.wsUrl || config.baseUrl || '').replace(/^http/, 'ws') const url = `${wsBase}/websocket?type=${type}` console.log(url) function connect() { manualClose = false // 使用 uni.connectSocket 建立连接(部分运行环境可能不支持 WebSocket,会直接抛异常) try { socket = uni.connectSocket({ url, success() { console.log('connectSocket 调用成功,等待 onOpen 回调') }, fail(err) { console.error('connectSocket 调用失败:', err) callbacks.onError && callbacks.onError(err) } }) } catch (err) { console.error('connectSocket 执行异常(可能环境不支持 WebSocket):', err) callbacks.onError && callbacks.onError(err) return } if (!socket) { console.error('connectSocket 未返回有效 socketTask') return } // 正确的事件注册方式:socketTask.onOpen / onMessage / onError / onClose socket.onOpen((res) => { console.log('WebSocket 已打开', res) // 检查回调是否已被清空 if (callbacks && callbacks.onOpen) { try { callbacks.onOpen(res) } catch (e) { // 忽略回调错误 } } }) socket.onMessage((evt) => { // H5 为 evt.data,小程序为 evt.data,统一兼容 const data = evt && (evt.data || evt) // 检查回调是否已被清空 if (callbacks && callbacks.onMessage) { try { callbacks.onMessage(data) } catch (e) { // 忽略回调错误,可能是组件已销毁 } } }) socket.onError((err) => { console.error('WebSocket 发生错误:', err) // 检查回调是否已被清空 if (callbacks && callbacks.onError) { try { callbacks.onError(err) } catch (e) { // 忽略回调错误 } } }) socket.onClose((evt) => { console.log('WebSocket 已关闭', evt) // 检查回调是否已被清空 if (callbacks && callbacks.onClose) { try { callbacks.onClose(evt) } catch (e) { // 忽略回调错误 } } if (!manualClose && callbacks) { setTimeout(connect, 3000) } }) } function close() { manualClose = true // 清空所有回调,防止在关闭过程中或关闭后触发回调 callbacks = { onOpen: null, onClose: null, onError: null, onMessage: null } if (socket) { try { socket.close(1000, 'client close') } catch (e) { // ignore } socket = null } } function send(data) { if (!socket) { console.error('WebSocket 未初始化,无法发送消息') return } // uni-app 的 socketTask.send 使用对象形式 socket.send({ data: JSON.stringify(data), fail(err) { console.error('发送 WebSocket 消息失败:', err) } }) } // 清空回调函数的方法 function clearCallbacks() { callbacks = { onOpen: null, onClose: null, onError: null, onMessage: null } } return { connect, close, send, clearCallbacks } }