uni-app X WebSocket 通信指南:connectSocket 全局 API 与 SocketTask 详解

发布时间:2026/9/21 22:03:09
uni-app X WebSocket 通信指南:connectSocket 全局 API 与 SocketTask 详解 uni-app X WebSocket 通信指南connectSocket 全局 API 与 SocketTask 详解【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app本文基于 uni-app 开源仓库中 docs/api/websocket.md 文档结合 uni-websocket 模块源码 与 示例页面 整理而成。读者将掌握uni.connectSocket的完整参数体系、SocketTask 对象的方法与事件模型、废弃全局 API 的迁移路径以及多连接场景下的正确选型可直接对照仓库源码与示例复现完整的 WebSocket 收发流程。一、先理解全局 API 与 SocketTask 的边界WebSocket 是 uni-app X 中实现全双工长连接通信的核心能力适用于即时通讯、消息推送、实时数据同步等场景。官方文档在开头就给出了本主题最重要的使用边界警告这也是后续所有接口设计的出发点uni.onSocketOpen、uni.onSocketError、uni.sendSocketMessage、uni.onSocketMessage、uni.closeSocket、uni.onSocketClose这组全局方法操作的始终是应用全局范围内创建的第一个 WebSocket 连接当应用中存在多个 WebSocket 连接时上述全局方法无法区分管理具体连接此时必须改用uni.connectSocket返回的SocketTask对象通过其onOpen、onError、send、onMessage、close、onClose方法进行单连接粒度的操作为了保证更好的兼容性官方明确建议不要使用uni上已废弃的onSocketOpen、onSocketError、sendSocketMessage、onSocketMessage、closeSocket、onSocketClose等方法应全部迁移到 SocketTask 方案。在 src/pages/API/websocket/websocket.uvue 的示例提示中官方进一步给出了一个真实的多连接冲突场景web 端和小程序端的 uni-push 功能、app-android 端和 app-ios 端的 web-view 组件日志回显、app-harmony 端的日志回显都会占用一个 socket 链接此时继续使用全局 socket API 会引发连接管理混乱必须使用 SocketTask 操作小程序端日志回显功能同样会占用一个 socket 链接如不需要可在 HBuilderX 控制台关闭日志回显。二、uni.connectSocket创建 WebSocket 连接uni.connectSocket(options)用于创建一个 WebSocket 连接。与 uni-appVue 版的全局单一连接模型不同uni-app X 中该接口返回 SocketTask 对象这是推荐的管理连接方式。2.1 平台兼容性| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 4.0 | 4.41 | 3.91 | 4.11 | 4.61 |上述版本号为对应平台支持connectSocket的起始版本。从 src/uni_modules/uni-websocket/utssdk/interface.uts 的类型标注可见该接口在 Android/iOS/HarmonyOS/微信小程序/web 均标记为支持支付宝、百度、抖音、飞书、QQ、快手、京东小程序则由宿主端提供。2.2 参数说明options的类型为ConnectSocketOptions属性描述如下| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | | :- | :- | :- | :- | :-: | :- | | url | string | 是 | | 微信小程序: 4.41; Android: 3.91; iOS: 4.11; HarmonyOS: 4.61 | 开发者服务器接口地址 | | header | UTSJSONObject | 否 | null | 微信小程序: 4.41; Android: 3.91; iOS: 4.11 | HTTP 请求 Headerheader 中不能设置 Referer | | protocols | Arraystring | 否 | null | 微信小程序: 4.41; Android: 3.91; iOS: 4.11 | 子协议数组 | | success | (result: ConnectSocketSuccess) void | 否 | null | | 接口调用成功的回调函数 | | fail | (result: ConnectSocketFail) void | 否 | null | | 接口调用失败的回调函数 | | complete | (result: any) void | 否 | null | | 接口调用结束的回调函数调用成功、失败都会执行 | | forceCellularNetwork | boolean | 否 | | 微信小程序: 4.41 | 需要基础库2.29.0强制使用蜂窝网络发送请求 | | perMessageDeflate | boolean | 否 | | 微信小程序: 4.41 | 需要基础库2.8.0是否开启压缩扩展 | | tcpNoDelay | boolean | 否 | | 微信小程序: 4.41 | 需要基础库2.4.0建立 TCP 连接时的 TCP_NODELAY 设置 | | timeout | number | 否 | | 微信小程序: 4.41 | 需要基础库2.10.0超时时间单位为毫秒 |注意forceCellularNetwork、perMessageDeflate、tcpNoDelay、timeout四个参数仅微信小程序端可用受宿主基础库版本限制在 App 端与 web 端并不生效。与 src/uni_modules/uni-websocket/utssdk/interface.uts 中ConnectSocketOptions的类型定义对比可发现仓库源码中实际声明的字段为url、header、protocols、success、fail、complete六个其余小程序专属字段由宿主环境透传。2.3 回调结果类型ConnectSocketSuccess连接调用成功的回调参数| 名称 | 类型 | 必备 | | :- | :- | :- | | errMsg | string | 是 |ConnectSocketFail连接调用失败的回调参数| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errCode | number | 是 | 错误码600009表示 URL 格式不合法 | | errSubject | string | 是 | 统一错误主题模块名称 | | data | any | 否 | 错误信息中包含的数据 | | cause | Error | 否 | 源错误信息可以包含多个错误详见 SourceError | | errMsg | string | 是 | |源码 interface.uts 中ConnectSocketFail实现了IUniError接口并将errCode约束为ConnectSocketErrorCode 600009这与 uni-app X 统一错误规范见 docs/err-spec.md保持一致。2.4 关键认知success 回调 ≠ 连接成功官方示例中特别强调了一个易混淆点uni.connectSocket的success回调是接口调用成功的回调不是连接建立成功的回调fail回调也只是接口调用失败的回调不是连接失败的回调。真正的连接打开 / 失败事件需要通过返回的 SocketTask 对象上的onOpen/onError来监听。这一点在 src/pages/API/websocket/websocket.uvue 的注释中写得很明确。2.5 返回值SocketTaskuni.connectSocket返回 SocketTask 对象这是多连接场景下操作 WebSocket 的唯一正确入口。三、SocketTask单连接粒度的操作对象SocketTask 提供了 6 个方法覆盖了连接生命周期内的全部操作。以下方法在 Web / 微信小程序 / Android / iOS / HarmonyOS 五个平台的支持版本均为Web 4.0、微信小程序 4.41、Android 3.91、iOS 4.11、HarmonyOS 4.61。3.1 send(options)发送数据task.send({ data: halo });SendSocketMessageOptions 属性描述| 名称 | 类型 | 必备 | 默认值 | 描述 | | :- | :- | :- | :- | :- | | data | any | 是 | | 需要发送的内容app 平台从 4.61 版本开始支持 ArrayBuffer | | success | (result: GeneralCallbackResult) void | 否 | null | 接口调用成功的回调函数 | | fail | (result: SendSocketMessageFail) void | 否 | null | 接口调用失败的回调函数 | | complete | (result: any) void | 否 | null | 接口调用结束的回调函数调用成功、失败都会执行 |SendSocketMessageFail 属性值继承统一错误结构| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errCode | number | 是 | 错误码 | | errSubject | string | 是 | 统一错误主题模块名称 | | data | any | 否 | 错误信息中包含的数据 | | cause | Error | 否 | 源错误信息 | | errMsg | string | 是 | |errCode 合法值| 合法值 | 描述 | | :- | :- | | 10001 | 发送数据超限发送队列不能超过 16M 大小 | | 10002 | websocket 未连接 | | 602001 | websocket 系统错误 |在 src/pages/API/websocket/socketTask.uvue 的示例中还演示了 ArrayBuffer 类型数据的发送方式构造new ArrayBuffer(2)后通过Int8Array写入字节再调用socketTask.send({ data })服务器返回的同样是 ArrayBuffer 类型。3.2 close(options)关闭连接task.close();CloseSocketOptions 属性描述| 名称 | 类型 | 必备 | 默认值 | 描述 | | :- | :- | :- | :- | :- | | code | number | 否 | 1000 | 数字值表示关闭连接的状态号关闭原因。未指定时默认 1000正常连接关闭 | | reason | string | 否 | | 可读字符串表示连接被关闭的原因。必须是不长于123 字节的 UTF-8 文本注意是字节不是字符数 | | success | (result: GeneralCallbackResult) void | 否 | null | 接口调用成功的回调函数 | | fail | (result: GeneralCallbackResult) void | 否 | null | 接口调用失败的回调函数 | | complete | (result: GeneralCallbackResult) void | 否 | null | 接口调用结束的回调函数调用成功、失败都会执行 |3.3 事件监听方法SocketTask 提供 4 个监听方法均在调用uni.connectSocket之后注册| 方法 | 签名 | 说明 | 回调结果 | | :- | :- | :- | :- | | onOpen | (callback: (result: OnSocketOpenCallbackResult) void) void | 监听 WebSocket 连接打开事件 |headerany连接成功的 HTTP 响应 Header | | onMessage | (callback: (result: OnSocketMessageCallbackResult) void) void | 监听 WebSocket 接收到服务器的消息事件 |dataany服务器返回的消息app 平台从 4.61 版本开始支持 ArrayBuffer | | onError | (callback: (result: GeneralCallbackResult) void) void | 监听 WebSocket 错误 |errMsgstring错误信息 | | onClose | (callback: (result: any) void) void | 监听 WebSocket 连接关闭事件 | 包含codenumber与reasonstring对应关闭状态号与关闭原因 |其中OnSocketCloseCallbackResult的code与reason均为必填字段分别表示关闭连接的状态号关闭原因和可读的关闭原因字符串见 interface.uts。四、已废弃的全局方法应迁移至 SocketTask以下 6 个挂在uni对象上的全局方法均已废弃官方标注使用 SocketTask 的对应方法替换仅建议在只需要管理唯一连接、且无 uni-push/日志回显等占用 socket 的旧项目中兼容使用| 废弃全局方法 | 作用 | 替换方案 | | :- | :- | :- | | uni.onSocketOpen(callback) | 监听 WebSocket 连接打开事件 | SocketTask.onOpen | | uni.onSocketError(callback) | 监听 WebSocket 错误 | SocketTask.onError | | uni.sendSocketMessage(options) | 通过 WebSocket 连接发送数据需先 connectSocket并在 onSocketOpen 回调之后才能发送 | SocketTask.send | | uni.onSocketMessage(callback) | 监听 WebSocket 接收到服务器的消息事件 | SocketTask.onMessage | | uni.closeSocket(options) | 关闭 WebSocket 连接 | SocketTask.close | | uni.onSocketClose(callback) | 监听 WebSocket 关闭 | SocketTask.onClose |注意即使使用全局方法uni.connectSocket返回的 SocketTask 依然可以同时使用但全局方法始终绑定到第一个创建的连接上混用时务必确认连接数量与归属避免管理错乱。这组废弃方法的回调签名与参数在 interface.uts 中均以deprecated标注并保留了完整类型定义。五、注意事项出于性能权衡底层实现中 WebSocket发送队列占用的内存不能超过 16M一旦超过将导致连接被关闭对应send失败错误码10001。高频发送场景下应注意控制积压数据量必要时做发送频率限流或拆分批次。六、完整实战示例从全局 API 到 SocketTask6.1 全局 API 版websocket.uvue以下代码取自仓库真实示例 src/pages/API/websocket/websocket.uvue演示了使用全局 API 的完整连接、收发、断开流程.uvue文件使用languts强类型脚本template view classuni-padding-wrap view classuni-btn-v text classwebsocket-msg{{ showMsg }}/text button typeprimary clickconnect连接websocket服务/button button v-showconnected typeprimary clicksend发送一条消息/button button typeprimary clickclose断开websocket服务/button text classwebsocket-tips发送消息后会收到一条服务器返回的消息与发送的消息内容一致/text button typeprimary clickgoSocketTask跳转 socketTask 示例/button /view /view /template script setup languts const connected ref(false) const connecting ref(false) const msg ref() const platform ref() const showMsg computed(() : string { if (connected.value) { return msg.value.length 0 ? 收到消息 msg.value : 等待接收消息 } return 尚未连接 }) onLoad(() { platform.value uni.getDeviceInfo().platform as string }) onUnload(() { uni.closeSocket({ code: 1000, reason: close reason from client, success: (res : any) console.log(uni.closeSocket success, res), fail: (err : any) console.log(uni.closeSocket fail, err), } as CloseSocketOptions) uni.hideLoading() }) const connect () { if (connected.value || connecting.value) { uni.showModal({ content: 正在连接或者已经连接请勿重复连接, showCancel: false }) return } connecting.value true uni.showLoading({ title: 连接中... }) uni.connectSocket({ url: wss://websocket.dcloud.net.cn, header: { test: uniapp x }, protocols: null, success: (res : any) { // 这里是接口调用成功的回调不是连接成功的回调请注意 console.log(uni.connectSocket success, res) }, fail: (err : any) { // 这里是接口调用失败的回调不是连接失败的回调请注意 console.log(uni.connectSocket fail, err) }, }) uni.onSocketOpen((res) { connecting.value false connected.value true uni.hideLoading() uni.showToast({ icon: none, title: 连接成功 }) console.log(onOpen, res) }) uni.onSocketError((err) { connecting.value false connected.value false uni.hideLoading() uni.showModal({ content: 连接失败可能是websocket服务不可用请稍后再试, showCancel: false }) console.log(onError, err) }) uni.onSocketMessage((res) { if (res.data instanceof ArrayBuffer) { var int8 new Int8Array(res.data) msg.value int8.toString() } else { msg.value res.data as string } console.log(onMessage, res) }) uni.onSocketClose((res) { connected.value false msg.value console.log(onClose, res) }) } const send () { uni.sendSocketMessage({ data: from platform.value : parseInt((Math.random() * 10000).toString()).toString(), success: (res : any) console.log(res), fail: (err : any) console.log(err), } as SendSocketMessageOptions) } const close () { uni.closeSocket({ code: 1000, reason: close reason from client, success: (res : any) console.log(uni.closeSocket success, res), fail: (err : any) console.log(uni.closeSocket fail, err), } as CloseSocketOptions) } const goSocketTask () { uni.navigateTo({ url: /pages/API/websocket/socketTask }) } /script该示例展示了三个值得沉淀的实战要点状态守卫用connected/connecting两个 ref 防止重复连接这是避免多个全局连接互相覆盖的第一道防线连接成功判定以uni.onSocketOpen回调为准更新 UI而非connectSocket.successArrayBuffer 兼容处理onSocketMessage回调中通过res.data instanceof ArrayBuffer分支处理二进制消息app 平台从 4.61 版本开始返回 ArrayBuffer 数据。6.2 SocketTask 版socketTask.uvue针对多连接场景仓库提供了对应的 SocketTask 示例 src/pages/API/websocket/socketTask.uvue。核心差异在于连接管理从全局唯一变为对象持有script setup languts const socketTask ref(null as SocketTask | null) function connect() { // 1. 建立连接并持有 SocketTask socketTask.value uni.connectSocket({ url: wss://websocket.dcloud.net.cn, success: (res : any) console.log(uni.connectSocket success, res), fail: (err : any) console.log(uni.connectSocket fail, err), }) // 2. 通过 task 注册生命周期事件 socketTask.value?.onOpen((res : any) { connecting.value false connected.value true uni.hideLoading() uni.showToast({ icon: none, title: 连接成功 }) }) socketTask.value?.onError((err : any) { connecting.value false connected.value false uni.hideLoading() uni.showModal({ content: 连接失败可能是websocket服务不可用请稍后再试, showCancel: false }) }) socketTask.value?.onMessage((res : OnSocketMessageCallbackResult) { if (res.data instanceof ArrayBuffer) { var int8 new Int8Array(res.data) msg.value int8.toString() } else { msg.value res.data as string } }) socketTask.value?.onClose((res : any) { connected.value false socketTask.value null msg.value }) } function send() { const data from platform.value : parseInt(Math.random() * 10000 ).toString() socketTask.value?.send({ data } as SendSocketMessageOptions) } function sendArrayBuffer() { const data new ArrayBuffer(2) let int8 new Int8Array(data) int8[0] 1 int8[1] 2 socketTask.value?.send({ data } as SendSocketMessageOptions) } function close() { socketTask.value?.close({ code: 1000, reason: close reason from client, success: (res : any) console.log(uni.closeSocket success, res), fail: (err : any) console.log(uni.closeSocket fail, err), } as CloseSocketOptions) } /script该示例还包含两个工程化细节onUnload页面卸载时通过task.close({ code: 1000, reason: close reason from client })主动释放连接避免页面销毁后 socket 泄漏defineExpose({ data, jest_connectSocket })暴露内部状态与方法供自动化测试配合同目录下 socketTask.test.js驱动验证。七、源码层面的实现印证在仓库 src/uni_modules/uni-websocket 模块中可以找到上述 API 的完整落点类型契约utssdk/interface.uts 定义了Uni接口中的connectSocket及全部废弃方法签名ConnectSocketOptions、SendSocketMessageOptions、CloseSocketOptions、OnSocketOpenCallbackResult、OnSocketMessageCallbackResult、OnSocketCloseCallbackResult等类型均在此声明与文档参数表一一对应Android 实现utssdk/app-android/index.uts 中connectSocket、sendSocketMessage、closeSocket、onSocketOpen、onSocketMessage、onSocketClose、onSocketError全部委托给WebSocketManager.getInstance()单例其内部管理着全局唯一的 socket 实例——这正是全局 API 只能操作第一个连接这一文档警告的底层原因连接细节封装在 WebSocketManager.uts 与 WebsockerClient.uts 中iOS / HarmonyOS 实现分别位于 utssdk/app-ios/index.uts 与 utssdk/app-harmony/index.uts其中 iOS 侧依赖仓库内置的websocket.xcframework原生框架。由此可以推断全局 API 与 SocketTask 并非两套底层实现而是同一连接对象上的两种操作视图——全局 API 固定操作单例管理器持有的第一个连接SocketTask 则将句柄暴露给业务层允许精确控制任意连接。这就是官方要求多连接时使用 SocketTask的根本原因。八、通用类型GeneralCallbackResult各接口 success/fail/complete 回调中广泛使用的通用结果类型| 名称 | 类型 | 必备 | 描述 | | :- | :- | :- | :- | | errMsg | string | 是 | 错误信息 |九、选型建议小结| 场景 | 推荐方案 | | :- | :- | | 仅需一个长连接、无 uni-push / 日志回显等占用 socket 的功能 | 可使用全局 API注意已废弃建议仍用 SocketTask | | 需要同时维持多个 WebSocket 连接 | 必须使用 SocketTask分别持有句柄管理 | | 需要发送 / 接收 ArrayBuffer 二进制数据 | SocketTask.send / onMessageapp 4.61 | | 页面销毁时释放连接 | onUnload 中调用 task.close({ code: 1000 }) | | 发送高频大量数据 | 关注 16M 发送队列上限控制积压 |相关参考文档docs/api/websocket-global.md旧版全局 API 文档入口、docs/err-spec.md统一错误规范、示例页面源码、SocketTask 示例、uni-websocket 模块实现。【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考