地铁里断网 40 秒,恢复后重新订阅,聊天窗少了 12 条,服务端日志显示这段时间广播是照常发出去的。乍看像缓存或者权限的锅,追下去往往不是。

SELECT id, room_id, payload FROM message
WHERE room_id = ? AND id > ?
ORDER BY id ASC LIMIT 200;

追下去是这么回事:广播只对当前连接集合发,掉线的人不在集合里,消息发完就没了。没有落库也没有游标,重连只能拿到之后的新消息,中间这段永远是空的。

碰到「离线消息补发」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。

具体做法是,每条广播消息落一张 message 表 带自增 id 和 room_id;客户端重连时带上最后收到的 id 拉增量;服务端按 id 升序返回大于游标的消息;补发完再切回实时推送 中间别留空窗。

验收就看一点,模拟断网 40 秒再恢复 客户端条数和服务端 message 表一致 缺口为 0。

作者 9823189