uni.connectSocket 是唯一可靠入口,App 和小程序中 new WebSocket() 无效,H5 编译跨端会断连;连接须在 onReady 后发起并校验网络;url 必用 wss:// 且参数需 encodeURIComponent 编码;首条消息仅可在 uni.onSocketOpen 中发送;data 发送前必须 JSON.stringify();消息类型依服务端决定;需手动实现指数退避重连并区分 onSocketClose code;应全局单例管理 socket 并集中维护连接状态。

uni.connectSocket 是唯一可靠入口,别用 new WebSocket() ——App 和小程序里它根本不会工作,H5 虽然能跑,但一编译到其他端就断连,跨端一致性直接崩。
连接必须等 onReady 之后再发起
在 onLoad 里调 uni.connectSocket 是常见翻车点,尤其 App 端页面还没真正挂载,底层网络栈可能未就绪,连接会静默失败或延迟超时。
正确时机是 onReady 触发后,或配合 uni.getNetworkType 检查网络可用性再连。
-
url必须带协议,生产环境强制用wss://(小程序硬性要求,H5/App 也应统一) - 查询参数如
?token=abc+def必须用encodeURIComponent编码,否则 + 号被当空格,服务端解析失败导致鉴权拒绝 - 不建议在
success回调里发消息——连接已“创建成功”,但通道未必 ready,uni.sendSocketMessage很可能报fail websocket not connected
uni.onSocketOpen 才是发首条消息的唯一安全时机
WebSocket 连接建立分两层:底层 TCP 握手完成(connectSocket success),上层协议握手完成(onSocketOpen)。只有后者触发,才能确保收发通道就绪。
- 发送文本前必须
JSON.stringify(),data只接受string或ArrayBuffer,传对象会静默丢弃 -
uni.onSocketMessage的event.data类型由服务端决定:文本 →string,二进制 →ArrayBuffer,不能假设一定是字符串 - H5 支持
binaryType: 'arraybuffer'配置,但 App 和小程序完全忽略该字段,一律按服务端实际帧类型处理
断连重连不能靠运气,得手动管生命周期
uni-app 不提供自动重连。掉线后不干预,用户就卡在“离线”状态。关键要监听三类事件并分类响应:
-
uni.onSocketError:连接过程出错(DNS 失败、证书问题等),立即尝试指数退避重连(1s → 3s → 9s…最多 5 次) -
uni.onSocketClose:连接关闭,检查event.code—— 小程序切后台是1001,属正常行为,不打错误日志;非 1000/1001 的 code 才需重连 - App 和小程序的
onHide:iOS 后台几秒内必断,Android 稍长但不可靠,此时应主动uni.closeSocket()并清空状态,避免 resume 时残留无效 task
全局单例管理比页面级连接更稳
多个页面各自 connectSocket,轻则触发服务端连接数限制,重则消息乱序、重复推送、心跳冲突。所有页面应共享同一个 socket 实例。
- 把初始化逻辑抽到
socket.js,暴露send()、onMessage(cb)、close()方法 - 用
uni.$emit/uni.$on或 Pinia store 中转消息,避免页面直接操作 socket API - 连接状态(
connecting/open/closed)必须集中维护,页面只订阅状态变更,不自行判断是否可发
console.log 也盖不住真实连接状态。


















