diff --git a/common/api.js b/common/api.js index 692999f..772adbe 100644 --- a/common/api.js +++ b/common/api.js @@ -106,6 +106,142 @@ function uploadRequest(url, params) { }) } +/** + * 使用 uni-app WebSocket API 实现的 WebSocket 类 + * 符合之前定义的 WebsocketInterface(无类型约束) + */ +class UniAppWebSocket { + /** + * 构造函数:传入 WebSocket 服务器地址 + * @param {string} host - 完整的 WebSocket URL,例如 'wss://example.com/ws' + */ + constructor(host) { + this.host = host; + // 事件回调属性(外部可赋值) + this.close = null; // 可赋值为函数,同时也可用主动关闭连接 + this.onopen = null; + this.onmessage = null; + // 内部 SocketTask 实例 + this.socketTask = null; + // 初始化连接 + this._initSocket(); + } + + /** + * 初始化 WebSocket 连接(私有方法,约定以 _ 开头) + */ + _initSocket() { + const self = this; + + // 创建 SocketTask + this.socketTask = uni.connectSocket({ + url: this.host, + success() { + // 连接创建成功(但尚未打开) + }, + fail(err) { + // 连接创建失败,触发错误事件 + const errorEvent = { type: 'error', error: err, target: self }; + self.onerror(errorEvent); + } + }); + + // 监听打开事件 + this.socketTask.onOpen((res) => { + if (self.onopen) { + // 构造一个简单的事件对象 + const event = { type: 'open', target: self, ...res }; + self.onopen(event); + } + }); + + // 监听消息事件 + this.socketTask.onMessage((res) => { + if (self.onmessage) { + // res.data 是消息数据 + const event = { + type: 'message', + data: res.data, + target: self + }; + self.onmessage(event); + } + }); + + // 监听关闭事件 + this.socketTask.onClose((res) => { + // 构造关闭事件 + const event = { + type: 'close', + code: res.code, + reason: res.reason, + wasClean: res.wasClean, + target: self + }; + // 调用 onclose 方法(可被重写) + self.onclose(event); + }); + + // 监听错误事件 + this.socketTask.onError((err) => { + const errorEvent = { type: 'error', error: err, target: self }; + self.onerror(errorEvent); + }); + + // 将 close 属性设置为一个可调用函数,用于主动断开连接 + // 同时也满足接口的 “回调类型” 定义 + this.close = function(ev) { + if (self.socketTask) { + const code = ev && ev.code ? ev.code : 1000; + const reason = ev && ev.reason ? ev.reason : ''; + self.socketTask.close({ code, reason }); + } + // 如果作为回调函数,返回 null 即可(无实际意义) + return null; + }; + } + + /** + * 关闭事件处理方法(可被外部重写) + * @param {Object} event - 关闭事件对象 + */ + onclose(event) { + // 默认空实现,你可以在外部覆盖此方法 + // console.log('连接已关闭', event); + } + + /** + * 错误事件处理方法(可被外部重写) + * @param {Object} event - 错误事件对象 + */ + onerror(event) { + // 默认空实现 + // console.error('连接错误', event); + } + + /** + * 发送数据 + * @param {string|ArrayBuffer|Blob} data - 要发送的数据 + * @throws {Error} 如果 WebSocket 未初始化 + */ + send(data) { + if (!this.socketTask) { + throw new Error('WebSocket 未初始化,无法发送数据'); + } + this.socketTask.send({ + data: data, + success() { + // 发送成功,可添加日志 + }, + fail(err) { + // 发送失败,触发错误事件 + const errorEvent = { type: 'error', error: err, target: this }; + this.onerror(errorEvent); + } + }); + } +} + // ========================================== // 初始化 SDK 实例 // ========================================== @@ -113,6 +249,7 @@ const client = new HaveADrink({ host: API_HOST, http_request: httpRequest, upload: uploadRequest, + websocket: UniAppWebSocket, token: uni.getStorageSync('auth_token') || '' })