微信小程序里虽然也能做 WebSocket 通信,但用法不能照搬浏览器端。它既不支持 new WebSocket(),也没有实例级事件和 readyState 这类常见能力,连接管理必须交给微信提供的专属 API。本文按“怎么建连、什么时候能发、断了怎么办、何时该关”四个问题展开,方便你快速搭出一套更稳的通信流程,并判断现有实现是否存在隐藏的断连风险。
必须先接受一个前提:只能用 wx.connectSocket 建连
在微信小程序环境中,浏览器原生的 new WebSocket() 不可用,必须改用微信提供的 wx.connectSocket。这套接口封装了底层连接能力,但也带来了更严格的生命周期约束。

其中最容易忽略的一点是:同一时间只允许一个活跃连接。如果在旧连接未关闭时再次调用 connectSocket,小程序会自动把已有连接关掉,再建立新的连接,两个 socket 不会并存。对业务来说,这意味着重复建连可能直接造成消息中断、异常关闭,甚至让你误判为服务端不稳定。
- 生产环境使用
wss://,本地调试可使用ws:// - 连接域名必须提前配置在小程序后台的「服务器域名」中
header中不能带Referer- 认证参数如
token可放在 URL 中,例如wss://api.example.com?uid=123&token=abc - 更适合在
app.js的onLaunch或页面的onLoad中初始化,避免被重复触发
如果你的项目里有多个页面都可能调用连接逻辑,最好从一开始就把“全局只维护一个连接”作为约束来设计,而不是等到切页和重进页面时再补救。
事件监听必须提前注册,success/fail 不能当作连上了
wx.connectSocket 的 success 和 fail,只表示“发起连接请求这一步是否成功”,并不代表连接已经真正建立。真正可靠的完成信号,是 wx.onSocketOpen。
这和浏览器环境有一个很大的差别:小程序的 WebSocket 监听器是全局监听,不是挂在某个 socket 实例上的方法。因此,注册时机必须提前,最好在调用 connectSocket 之前就把相关监听全部准备好。
- 先注册
wx.onSocketOpen - 同时注册
wx.onSocketError、wx.onSocketClose、wx.onSocketMessage - 不要把连接成功的判断写在
success回调里
如果还没等到 onSocketOpen 就执行 wx.sendSocketMessage,通常会直接报错:Still in CONNECTING state。这个报错本质上不是发送逻辑写错,而是发送时机错了。
为什么这一步最容易埋坑
很多浏览器端代码迁移到小程序时,会保留“创建实例后立刻绑定事件,再尝试发送首条消息”的习惯。但在小程序里没有这套实例模型,监听器晚注册、业务层又抢先发送,就很容易出现首包丢失或者连接状态判断失真。
更稳妥的做法是,把监听注册和建连初始化放在同一处统一管理,让页面只关心“当前是否可发消息”,而不是各自操作 socket 生命周期。
发送与接收的关键:只在 OPEN 之后发,并自己维护状态
小程序环境没有浏览器里常见的 socket.readyState,也就是说,你不能靠读取实例状态来决定当前是否能发消息。要想把发送逻辑跑稳,最实际的方法就是自己维护一份连接状态。

- 只在
onSocketOpen触发后允许发送消息 - 可维护全局变量,例如
App.globalData.socketConnected = true - 发送失败时检查
fail回调,定位是否未连上、已断开,或者数据格式不合法
消息数据本身也有限制。wx.sendSocketMessage 接收的数据类型只支持 string 或 ArrayBuffer。如果传了不符合要求的对象类型,即使连接本身没有问题,也会发送失败。
因此,业务上至少要守住两条规则:一是连接打开前不发送,二是所有待发送数据在出手前先明确序列化格式。这样能减少大量看起来像“偶发断连”的假问题。
小程序不会帮你自动重连,心跳和重试都要自己补
微信小程序不会自动重连,也不会内建 ping/pong 保活机制。只要网络波动、服务端主动断开,或者客户端长时间无通信,连接都可能中断。要让 WebSocket 真正能长期稳定工作,就必须补上重连和心跳策略。
常见做法是:在 onSocketClose 和 onSocketError 中安排延迟重连,例如 3 秒后再次调用 connectSocket。但重连不能无限循环,通常还要加上重试上限,比如最多 5 次,避免在异常状态下持续消耗资源。
- 断开后延迟重连,例如 3 秒后重试
- 限制重试次数,例如最多 5 次
- 定时发送心跳包,例如
{type: 'ping'} - 服务端返回
pong,若超时未收到响应,则主动关闭后再重连
这里的核心不是“有没有重连”,而是“重连是否有边界、心跳是否能判断假存活”。如果只是一断就立刻连、一直连到底,出了问题往往更难排查。
连接不用了要主动关,别把回收交给页面生命周期
在不再需要通信时,应显式调用 wx.closeSocket,而不是指望页面卸载、切后台或者系统自动帮你处理。主动关闭能避免连接残留,也能减少下一次进入页面时被旧状态干扰。
以下几种场景都适合明确关闭连接:
- 页面
onUnload或onHide时,如果不需要后台保持连接 - 用户退出登录时
- 服务端通知需要断开连接时,例如
token已失效
即使已经调用了 wx.closeSocket,也不要省略 onSocketClose 监听。因为从调用关闭到真正关闭完成,中间仍然是一个异步过程,监听关闭事件才能确认生命周期已经走完。
如果把这几个规则收束成一句话,那就是:微信小程序里的 WebSocket 更像一个需要手动托管的全局通信通道,而不是浏览器里拿来即用的实例对象。只要你把建连入口、监听注册、发送时机、重连策略和关闭时机统一起来,通信稳定性通常就能明显提升。









