微信小程序WebSocket连接失败主因是wss域名未在公众平台配置白名单;需单独添加ws子域名、禁用路径、测试版需开启debug;状态判断应以socketTask.readyState为准;心跳必须在onOpen中启动;重连须防抖退避并重置socketTask。
微信小程序 WebSocket 连接失败:先看 wss:// 域名是否已配白名单
线上环境连接不上,90% 的原因是没在微信公众平台配置合法域名。微信强制要求线上版 websocket 必须使用 wss:// 协议,且域名必须提前填入「开发管理 → 开发者工具 → 服务器域名」里的 socket 合法域名 栏位。
常见踩坑点:
- 填了
https://api.example.com,但 WebSocket 地址是wss://ws.example.com—— 两个域名不一致,必须单独添加ws.example.com - 填了带路径的地址如
wss://api.example.com/ws—— 白名单只认一级域名(或二级域名),路径会被忽略,填错直接拒绝连接 - 测试版和正式版共用一套配置,但测试版未开启「调试基础库版本」或未勾选「启用调试」—— 测试版需手动开启 debug 模式才允许连接未备案域名(仅限测试)
closesocket:fail websocket is not connected 错误本质是状态不同步
这个错误不是“调用错了”,而是你代码里假设连接还活着,其实它早就断了。触发时机很典型:页面 onUnload 时执行 wx.closeSocket(),但此时连接可能已被微信后台自动关闭(比如切到其他 App),onClose 回调还没来得及触发,状态变量仍为 true。
解决关键不在“怎么关”,而在“怎么知道该不该关”:
- 不要依赖全局变量或 this.isSocketOpen 判断,改用
socketTask.readyState实时查 ——1才代表 OPEN 状态 - 所有发送、关闭操作前加判断:
if (socketTask && socketTask.readyState === 1) - 在
onClose和onError回调里立刻把 socketTask 置为 null,并清空定时器(比如心跳clearInterval(this.heartbeatTimer))
心跳包发不出去?先确认 onOpen 是否真被触发
很多开发者在 success 回调里就启动心跳,但微信小程序的 success 只表示“发起连接请求成功”,不代表握手完成。真正可靠的状态锚点只有 onOpen。
iOS 和 Android 表现还不一样:
- iOS 平台若没写
complete回调,onOpen可能压根不触发 —— 必须补上空的complete: () => {} - 微信开发者工具某些版本(如 8.0.41)对
onOpen有延迟或丢失,真机调试更准 - 心跳逻辑别写在
success或connectSocket外层,严格锁死在socketTask.onOpen(() => { ... })内部
重连失败反复报 websocket is closed before the connection is established
这个错误说明连接还没建立完就被中断了,不是后端拒收,而是客户端主动掐断。高频场景是:重连逻辑没做节流,网络差时瞬间触发十几次 wx.connectSocket(),微信底层会丢弃后续请求。
实操建议:
- 加防抖:两次
connectSocket调用间隔至少 3 秒,用setTimeout控制,别用setInterval - 退避策略:首次失败等 1s,第二次等 2s,第三次等 4s……最大不超过 30s,避免雪崩
- 检查是否在
onClose里重复调用了connect()—— 如果服务端主动断连(如 token 过期),应先清理状态再决定是否重连
最易被忽略的一点:重连时没重置 socketTask 引用。旧 task 对象若处于 CLOSED 或 CONNECTING 状态,再调 send 或 close 就会触发各种奇怪错误。每次重连前务必赋值 this.socketTask = null。











