微信小程序WebSocket必须用wx.connectSocket,不支持new WebSocket();需配置wss合法域名、正确监听onSocketOpen/onSocketMessage,且header与protocols须匹配服务端要求。

微信小程序 WebSocket 连接必须用 wx.connectSocket,不能用 new WebSocket()
小程序环境不支持浏览器原生 WebSocket 构造函数,直接写 new WebSocket('wss://...') 会报 ReferenceError: WebSocket is not defined。必须使用微信提供的 wx.connectSocket API,它才是唯一合法入口。
常见错误现象:
- 在开发者工具里能连上,真机断连 —— 很可能没配合法域名或用了
ws://(必须wss://) - 调用
wx.connectSocket后没反应 —— 忘了监听onOpen,或把监听写在了success回调里(已废弃) - 连接成功但收不到消息 —— 没正确绑定
wx.onSocketMessage,且该监听必须在连接建立前注册(推荐在onLoad就设好)
实操建议:
-
url参数必须是wss://开头,且域名需在「微信公众平台 → 开发管理 → 开发设置 → socket 合法域名」中提前备案并添加 - 不要在
connectSocket的success或fail里处理业务逻辑,它们只表示 API 调用是否发起成功,不反映连接状态 - 所有事件监听(
onOpen、onMessage、onClose、onError)必须用wx.onSocketXXX全局方法注册,且建议在页面onLoad阶段一次性完成
wx.connectSocket 的 header 和 protocols 怎么用
这两个参数不是摆设,尤其在需要身份透传或协议协商时很关键。
使用场景:
-
header:常用于携带用户 token 或设备信息,比如{ 'X-User-ID': '123', 'X-Auth-Token': 'abc' },服务端可在握手阶段校验,避免连接后还要额外鉴权 -
protocols:数组类型,如['chat-v2', 'json'],服务端可据此选择子协议(subprotocol),比如区分聊天、通知、心跳等不同用途的连接通道
注意点:
将产业文章整理为适合微信公众号/服务号发布的研究型草稿,支持原文读取、分层摘要、产业链标的梳理、image2 海报与封面生成、正文排版、微信草稿保存、回读校验和发布前确认。适用于鹊桥产业等服务号的半导体、AI 算力、先进封装、光通信、新能源、机器人等产业链研究内容。
-
header中的 key 不支持下划线(_),部分服务器(如 Nginx 反向代理)会自动过滤带下划线的 header,建议用短横线(X-User-Id) -
protocols必须和服务端返回的Sec-WebSocket-Protocol响应头完全匹配,否则连接会被关闭 - 微信开发者工具对
header支持较全,但某些安卓低版本真机可能忽略自定义 header,建议服务端同时支持 query 参数 fallback(如wss://api.example.com/chat?uid=123&token=abc)
消息收发必须区分 wx.sendSocketMessage 和 wx.onSocketMessage 的生命周期
很多人以为发消息就是调一次 wx.sendSocketMessage,收消息靠 onSocketMessage 监听 —— 这没错,但容易忽略两个致命前提:
- 发送前必须确保连接已就绪(
readyState === 1),否则会静默失败;建议加一层状态判断:if (wx.getStorageSync('wsReady')) { wx.sendSocketMessage(...) } -
onSocketMessage是全局监听,只要页面没销毁就会持续生效,但它的回调参数res.data类型不固定:文本消息是string,二进制消息是ArrayBuffer,务必用typeof res.data === 'string'判断后再JSON.parse
典型错误:
- 在
onSocketOpen回调里立刻发登录消息,但此时连接刚建立,服务端可能还没完成 session 初始化,导致消息被丢弃 - 收到消息后直接
this.setData({ messages: [...this.data.messages, res.data] }),如果res.data是 ArrayBuffer,会触发渲染异常 - 频繁调用
sendSocketMessage且不节流,遇到网络抖动时堆积大量未发送任务,最终连接被服务端踢出
建议做法:
- 连接成功后先发一条轻量
auth消息,服务端验证通过再返回{"type":"auth_ok"},客户端收到后再允许 UI 交互 - 对发送操作做简单队列封装,避免并发冲突;对大消息(如图片 base64)拆包或改走 HTTP 上传
真机调试连不上?重点查这三处配置
开发者工具能通 ≠ 真机能通,90% 的真机连接失败卡在这三个地方:
-
域名未备案或未填入「socket 合法域名」:必须是完整域名(如
api.example.com),不能带路径或端口;国内服务器必须有 ICP 备案号,且备案主体需与小程序主体一致 -
证书问题:服务端
wss://使用的 SSL 证书必须由可信 CA 签发(Let’s Encrypt 可以),自签名证书、过期证书、域名不匹配都会导致 iOS/Android 拒绝连接 -
防火墙或反向代理拦截:Nginx 配置里漏了
proxy_http_version 1.1和proxy_set_header Upgrade $http_upgrade,会导致 WebSocket 握手失败,错误日志里常出现101 Switching Protocols缺失
调试技巧:
- 在手机微信「发现 → 小程序 → 右上角… → 设置 → 切换调试基础库版本」,选最低兼容版(如 2.28.0)测试兼容性
- 用
wx.getNetworkType确认当前是 wifi 还是 4G/5G,部分运营商会对非 443 端口的 wss 流量限速或拦截 - 服务端开启详细日志,重点关注 WebSocket 握手阶段的请求头(尤其是
Sec-WebSocket-Key和Origin)是否被篡改或丢失
最常被忽略的是:小程序的「开发版」「体验版」「正式版」对应三套独立的「socket 合法域名」配置,切版本后必须重新检查,不能只配一个。


















