onmessage未触发主因是前端监听未正确挂载;需确保wx.onsocketmessage在wx.onsocketopen后注册,避免覆盖、生命周期干扰及假连接,配合心跳、网络状态监听与重连机制。

onmessage 回调没触发?先确认连接状态和注册时机
小程序里 onsocketmessage 不执行,90% 不是后端没发,而是前端压根没“挂上钩”。常见情况包括:注册顺序错乱、页面生命周期干扰、或回调被覆盖。
-
wx.onsocketmessage必须在wx.connectSocket之后、且在wx.onsocketopen触发之后再调用才可靠;提前注册可能被忽略 - 页面
onHide或onUnload中若调用了wx.closeSocket,但未重置监听器,再次进入时onsocketmessage不会自动恢复 - 多个页面共用一个 socket 实例时,后注册的监听器会覆盖前一个——检查是否重复调用
wx.onsocketmessage
连接显示 OPEN 却收不到消息?查心跳与空闲断连
微信小程序底层 socket 在无数据交互超 60 秒后,会被系统或中间件(如 Nginx、云 WAF)静默关闭,而 readyState 仍维持 1(OPEN),onclose 也不触发。这是最隐蔽的“假连接”。
- 必须在
onopen后立即启动定时心跳:wx.sendSocketMessage({ data: 'ping' }),间隔建议 ≤30 秒 - 服务端需响应
pong或至少不关闭该连接;若用 Spring Boot,检查ReactorNettyWebSocketService的maxIdleTime是否设为 0 或足够大 - iOS 线上版尤其敏感,Android 和开发工具常表现正常,容易误判为兼容性问题
收到空字符串、乱码或 JSON 解析失败?你读到的是原始帧
小程序 onsocketmessage 回调里的 res.data 是解码后的文本或 ArrayBuffer,但如果你在自研网关、PHP/Node 原生 WebSocket 服务中直接 socket_read,拿到的就是带掩码、opcode、扩展长度字段的原始二进制帧——不是 UTF-8,也不是 JSON。
- 必须手动解析前 2 字节:
res.data若为ArrayBuffer,需用Uint8Array读取第 0 字节低 4 位(opcode === 0x1才是 Text) - MASK 位为 1 时,后续 4 字节是掩码 key,payload 每字节需异或对应 key 字节(循环)才能还原真实内容
- 长度字段为 126 或 127 时,要额外读取 2 或 8 字节扩展长度,跳过这些直接
JSON.parse必然返回null
域名、证书、网络切换全都没问题,还是收不到?检查 onnetworkstatuschange 是否触发重连
微信小程序在 Wi-Fi 切 4G、飞行模式进出、甚至后台切前台时,底层 socket 句柄会失效,但不会自动重连,也不会触发 onclose 或 onerror。这是真机高频问题,开发工具无法复现。
- 必须显式监听
wx.onNetworkStatusChange,并在connected: false时调用wx.closeSocket,connected: true时主动重建连接 - 不要依赖
onClose做唯一清理入口;每次重连前应先检查wx.getConnectedSocket(若支持)或自行维护连接状态标志位 - 重连前加随机延迟(如 100–500ms),避免多页面同时触发雪崩请求











