线上websocket连不上90%是域名、证书或配置问题:微信小程序要求wss协议且域名须在后台白名单配置(仅二级及以上域名,不带协议端口),修改后需提审;tls握手失败需检查证书可信性、反代透传upgrade头、443端口及云厂商websocket开关;开发调试需关闭域名校验;连接需在onlaunch/onload后调用并防重复;需监听onclose/onerror做延时重连与状态清理;单用户连接数限3~5个,须全局单例管理。

线上环境 WebSocket 连不上,90% 是域名、证书或配置没对齐,不是代码写错了。
wss:// 域名未配置白名单
微信小程序强制要求线上环境必须使用 wss:// 协议,且该域名必须提前在「微信公众平台 → 开发管理 → 开发设置 → 服务器域名」中填入「socket 合法域名」栏。注意:
- 只支持二级及以上域名(如
api.example.com),不支持 IP、localhost、127.0.0.1或三级测试域名(如test.api.example.com未显式添加则无效) - 填写时不能带协议、端口、路径(错误示例:
wss://api.example.com:443/ws;正确示例:api.example.com) - 修改后需重新提交小程序审核(仅配置项变更也需提审),灰度发布/体验版不会自动生效
TLS handshake failed(errCode: 1004)
这个错误本质是客户端和服务器在建立加密连接时失败,和前端 JS 逻辑无关,重点查服务端:
- 确认 SSL 证书由可信 CA 签发(Let’s Encrypt、DigiCert 等),
self-signed或过期证书会被微信直接拒绝 - 检查 Nginx / Caddy 是否透传了 WebSocket 升级头,关键配置不能少:
Upgrade、Connection: upgrade - 确保服务端监听的是 443 端口(wss 默认端口),且防火墙放行;若用非标端口(如 8080),微信会直接拦截
- 部分云厂商(如腾讯云 CLB)需手动开启「WebSocket 支持」开关,否则握手包被静默丢弃
connectSocket 调用后无响应或报 closed before established
常见于开发阶段误配或时机错误:
- 微信开发者工具默认校验域名,本地调试时务必勾选「不校验合法域名」(设置 → 项目设置 → 本地设置)
- 真机调试时,也要在「详情 → 本地设置」里打开同一开关,否则即使域名已白名单也连不上
-
wx.connectSocket必须在App.onLaunch或页面onLoad之后调用,不能放在模块顶层或异步回调外立即执行 - 避免重复调用:未判断
this.socket是否已存在就再次wx.connectSocket,会导致前一个连接被系统强制中断
onClose / onError 触发但没重连或状态混乱
小程序的 WebSocket 生命周期受微信管控,后台/切页时可能被主动回收,不能依赖浏览器行为:
- 必须监听
socketTask.onClose和socketTask.onError,并在回调里显式调用清理逻辑(如clearInterval(this.heartbeatTimer)) - 不要在
onClose里直接重连,应加延时(如setTimeout(() => this.connect(), 3000)),否则可能触发频率限制 - 每次调用
wx.connectSocket返回的socketTask是新实例,旧实例的监听器不会自动迁移,需手动解绑再重新绑定 - readyState 判断要严谨:仅当
socket.readyState === 1(OPEN)才发消息,0(CONNECTING)或2(CLOSING)都应缓存待发队列
最易忽略的一点:微信对单个用户同一时间的 WebSocket 连接数做了硬限制(实测约 3~5 个),多个页面或组件各自 new 一个 WsManager 实例却没做全局单例管理,就会出现偶发 connection refused —— 此时日志里看不到服务端请求,问题根本不在后端。











