先定位:丢的是离线存储还是重连拉取
发送方显示“已发送”,接收方重新上线后仍收不到,先对照三种现象:所有设备都收不到,是服务端没有写入离线队列;只有某台设备收不到,是客户端重连后没有按会话补拉;同一账号多台设备消息互相覆盖,是多端同步策略有误。判断清楚再动手,避免盲目换服务器或改协议。
最容易忽略的三个原因
- 离线消息队列未启用或 TTL 过短。服务端只做实时转发,未按接收者 ID 存储,或过期时间太短,稍晚上线消息已被清理。
- WebSocket 断线后没有持久会话与补拉机制。客户端重连后不带本地最后消息 ID 或时间戳同步,断线期间消息不返回。使用 WebSocket 实现即时通讯时,连接只是通道,不能替代离线存储和补拉。
- 多端同步按“最新端”覆盖,而不是按消息 ID 去重。多设备同时在线时,状态同步被误当成确认,导致未拉取消息被标记已读或清除,表现为重复推送或丢失。
修复步骤:按链路逐一补齐
- 服务端开启离线存储并设置合理 TTL。按接收者 ID 写入独立队列,至少保留 7 天;群聊按成员维度写入。
- 客户端重连后带游标补拉。用本地最大消息 ID 或最后同步时间请求增量消息,按 ID 合并,覆盖重连和前台恢复。
- 多端同步改为去重合并。服务端下发全局唯一 ID,客户端按 ID 去重,不按“最后在线设备”覆盖,同时避免离线丢失和重复推送。
- 连接失败先排查心跳与升级路径。若 WebSocket 频繁断开,检查心跳间隔、代理超时和移动网络切换;必要时退回 HTTP 长轮询。排查连接失败时,先看客户端是否拿到重连事件,再查会话是否失效;同时确认心跳延迟,避免把延迟高误判为离线丢失。
验证与边界:私有化与SaaS差异
弱网下杀进程再打开、断网 10 分钟后恢复、同一账号双设备同时在线,三组都能收到且不重复,说明链路完整。私有化部署可自定义 TTL 和多端同步;SaaS 受平台限制。企业IM私有化与SaaS对比,离线消息是刚需时优先看私有化是否暴露离线队列参数,可参考三方IM即时通讯系统定制开发与私有化部署解决方案。即时通讯软件怎么选,不能只看实时到达率,还要把离线补偿当作验收项。自建方案要关注消息可靠性隐性成本,成本拆解:自建即时通讯需要多少钱,包含哪些隐性支出有完整科目。
常见问题
怎么判断是服务端没存还是客户端没拉?
所有设备都收不到,查服务端离线队列;只有某台设备收不到,抓重连后的补拉请求,看是否携带游标。
XMPP 和 WebSocket 哪种更不易丢离线消息?
XMPP 自带离线规范,但服务端不实现也会丢;WebSocket 只是通道,必须上层补存储和同步。
消息重复推送与离线丢失是同一个问题吗?
经常同源:多端同步用覆盖而非去重,会导致部分端丢失、部分端重复。先查全局消息 ID 与去重逻辑。
企业选私有化还是 SaaS 更利于离线消息可控?
私有化通常可自定义 TTL 和同步参数;SaaS 需确认是否开放离线策略。能力边界可看企业IM聊天软件稳定性全面升级和极光鸟IM即时通讯系统是什么。