安卓真机websocket连接失败主因是manifest.json未配置合法域名、wss证书不被信任、url路径匹配错误;需显式填写wss://域名+端口、使用正规ca证书、传multiple:true并绑定sockettask.onmessage。

Uni-app开发WebSocket聊天功能,真机连接失败不是代码写错了,而是安卓端对协议、证书、配置的校验比浏览器和iOS更严格。绝大多数问题出在 manifest.json 配置、WSS证书信任、URL路径匹配这三点上,而不是WebSocket逻辑本身。
安卓真机连不上WSS:先看 manifest.json 有没有配对
安卓原生层会拦截未声明的WebSocket域名,即使你写了 wss://your-domain.com,只要没在 manifest.json 的「WebSocket合法域名」里显式填入,连接就会静默失败(无报错、无回调)。
- 打开 HBuilderX → 项目 →
manifest.json→ 「App SDK配置」→「WebSocket合法域名」 - 必须填完整协议+域名+端口(如
wss://api.example.com),不能只填api.example.com,也不能带路径(/ws不支持) - 如果后端用的是自定义端口(如
wss://api.example.com:8080),端口必须明确写出,否则安卓默认走443,握手直接被拒绝 - 注意:这个配置只影响 App 端,H5 和小程序需各自单独配置合法域名
WSS握手失败:检查证书是否被安卓信任
安卓系统(尤其 Android 7+)默认不信任自签名证书或 Let’s Encrypt 旧链证书。浏览器可能“点继续就能进”,但 uni-app 打包的 App 会直接终止 TLS 握手,表现为 fail 回调触发,err 里是空对象或 net::ERR_CERT_AUTHORITY_INVALID 类似错误。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 用手机浏览器访问
https://your-domain.com,确认地址栏有锁图标且不提示证书风险 - 若用的是自签名证书,必须在安卓设备上手动安装 CA 证书并设为“系统级信任”(仅开发测试可用,不可上架)
- 生产环境建议用正规 CA(如 Sectigo、DigiCert)签发的证书,避免 Let’s Encrypt 的交叉链兼容问题
- Nginx 配置中确保
ssl_protocols TLSv1.2 TLSv1.3,低版本安卓(如 5.x)不支持 TLS 1.3,但强制关闭 TLS 1.2 会导致握手失败
连接成功但 onOpen 不触发:multiple 和 complete 回调缺一不可
安卓平台下,uni.connectSocket 返回的 socketTask 对象可能为 undefined,导致后续 onOpen、onMessage 绑定失效。这不是 Bug,而是安卓 WebView 的行为差异。
- 必须传入
multiple: true参数,否则某些安卓机型(尤其定制 ROM)不会返回有效socketTask -
success回调只表示“连接请求已发出”,不代表连接建立;fail表示请求发不出去(网络不通/域名未白名单);真正可靠的连接确认只有onOpen - iOS 要求必须写
complete回调,否则onOpen可能不触发;安卓虽不强制,但统一加上可避免跨端不一致 - 正确写法示例:
const socketTask = uni.connectSocket({<br> url: 'wss://api.example.com/ws',<br> multiple: true,<br> success: () => console.log('请求已发出'),<br> fail: (err) => console.error('请求失败', err),<br> complete: () => console.log('初始化完成')<br>});<br>socketTask.onOpen(() => console.log('实际连接成功'));
消息收发异常:别依赖 onSocketMessage 全局监听
在 App 端,全局 uni.onSocketMessage 在页面切换或组件卸载后仍可能被触发,造成内存泄漏或重复解析;同时,安卓 WebView 对二进制数据处理不稳定,容易把多条消息粘成一个 ArrayBuffer 或拆成多次回调。
- 务必使用
socketTask.onMessage绑定到具体实例,而非全局监听 - 发送前统一
JSON.stringify(),接收后先判断typeof res.data === 'string'再JSON.parse(),否则遇到 ArrayBuffer 会直接报错 - 服务端若一次推送多条消息,前端需自行实现分帧逻辑(如每条前加 4 字节长度头),不能假设每次回调对应一条业务消息
- 页面退后台时主动
uni.closeSocket(),避免系统回收连接后残留句柄引发下次连接失败
最常被忽略的是:安卓真机调试必须用自定义基座(或勾选「启用WebView调试」),否则所有 WebSocket 请求都会被阉割——这个开关不在代码里,而在 HBuilderX 的运行配置中。










