排查即时通讯消息发送失败原因时,第一步不是检查网络,而是确认失败形态。发送失败通常只有两类:即时错误——调用接口立刻返回错误码、超时或异常;假成功——消息在本地显示已发送,但对方收不到或延迟很久。前者优先查端侧状态和连接层;后者大概率在服务端存储、路由或策略。
下面按“端侧—连接层—服务侧”三层推进。
先用两个现象判断故障层:即时错误 vs 假成功
- 即时错误:发送请求立即返回 401、403、413 或网络超时。优先看 SDK 初始化状态、Token 权限和消息体限制。
- 假成功:本端发送完成,其他端收不到。优先看服务端离线消息存储、队列积压和策略命中。
层面一:端侧发送失败——SDK初始化、Token与消息格式
发送动作在离开设备前就可能失败,多数是配置问题而非网络问题。逐个核对以下项:
- SDK 未完成初始化或 init 回调未返回成功,就直接调用发送接口,会得到“未初始化”或 -1 一类错误。
- Token 过期或权限不足。返回 401/403 时,先查看服务端 token 有效期和当前用户权限,不要急着改网络。
- 消息体超限。文本长度、图片大小或自定义字段超过服务端限制,常见返回码为 413 或 400。
- 自定义消息格式不匹配。扩展字段类型与协议定义不一致,会导致序列化失败。
- 本地网络拦截。企业防火墙或安全软件可能阻断到消息网关的请求,可用最小请求复现判断。
层面二:连接层“假在线”——长连接断开、心跳与重连
界面显示在线不等于长连接真正可用。很多“发不出去”是连接半开或被静默断开,发送端仍在往一个失效连接写数据。
- 心跳间隔不合理。服务端已判定连接超时并回收,客户端却仍显示在线。
- 网络切换后未重连。从 Wi-Fi 切到移动网络时,旧连接没有及时释放,新的发送请求被挂起。
- App 被系统后台杀死。长连接断开后没有重建,退回前台时仍显示旧状态。
- TLS 证书校验失败。私有化环境使用自签证书时,客户端可能静默断开。
判断标准不是看 App 顶部状态,而是抓包确认是否还有心跳上行,或查看客户端重连日志里是否有 reconnect 失败记录。
层面三:服务端策略与存储——消息被丢弃、限制或风控拦截
到了服务端但对方收不到,通常不是消息没进系统,而是被存储策略、路由规则或风控逻辑拦下。
- 离线消息未存储或存储失败。接收方上线后拉不到历史,可参考离线消息收不到的常见原因与修复。
- 消息队列积压。服务端已接收但投递线程来不及处理,表现为延迟而非立即失败。
- 频率限制触发。同一用户短时间大量发送,触发限流后消息被静默丢弃。
- 敏感词或风控策略误拦。命中策略后不返回错误,消息直接不投递。
- 多端同步覆盖。新消息被旧消息的同步动作覆盖,导致部分端看到“已发送”但内容缺失。
处理时先查服务端日志中的消息状态、队列深度和策略命中记录,不要只盯客户端错误码。
常见问题
为什么消息显示发送成功但对方收不到?
多数是服务端离线消息未存储、队列积压或风控策略静默丢弃,先查服务端消息状态而不是网络。
