Reason Code
完整查阅当前 0–29 协议原因码的名称、阶段、重试建议和可达性。
目标与完成标准
本页把当前 pkg/protocol/frame.ReasonCode 枚举完整映射为开发者决策。完成后,你应能保留原始数值,结合 CONNACK、SENDACK 等阶段解释它,并执行有界、不会放大故障的重试策略。
兼容目标
下表由 Go 权威枚举与共享元数据生成,并由 CI 校验数值 0–29 和名称。它绑定当前 API 兼容快照,不会在中英文 MDX 中各维护一份手写副本。
| 值 / 名称 | 阶段 | 重试指引 | 可达性 | 说明 |
|---|---|---|---|---|
0ReasonUnknown | CONNECT / SEND | 由应用策略决定 | 兼容路径 | 未分类或未知结果;先保留上下文并停止盲目重试。 |
1ReasonSuccess | CONNECT / SEND | 不适用 | 当前路径可达 | 请求成功;具体完成边界取决于数据包类型。 |
2ReasonAuthFail | CONNECT / SEND | 修复请求后再操作 | 当前路径可达 | 认证或发送身份被拒绝;先修复凭据或服务端策略。 |
3ReasonSubscriberNotExist | SEND | 修复请求后再操作 | 当前路径可达 | 发送者不在要求的频道成员集合中。 |
4ReasonInBlacklist | SEND | 修复请求后再操作 | 当前路径可达 | 发送者命中频道黑名单。 |
5ReasonChannelNotExist | SEND | 由应用策略决定 | 当前路径可达 | 频道不存在或当前不能接收该发送。 |
6ReasonUserNotOnNode | CONNECT / delivery | 刷新路由后复用幂等键 | 兼容路径 | 目标用户不在当前节点;刷新路由后再决定是否重试。 |
7ReasonSenderOffline | SEND | 由应用策略决定 | 保留 | 保留的发送者离线结果;当前产品路径未发出该值。 |
8ReasonMsgKeyError | SEND | 修复请求后再操作 | 保留 | 保留的消息密钥或完整性错误;当前产品路径未发出该值。 |
9ReasonPayloadDecodeError | SEND | 修复请求后再操作 | 当前路径可达 | SEND 请求(字段或载荷)格式错误或不受支持,包括解码失败。 |
10ReasonForwardSendPacketError | SEND | 有界退避重试 | 兼容路径 | 兼容转发路径未能转发发送包。 |
11ReasonNotAllowSend | SEND | 修复请求后再操作 | 当前路径可达 | 频道策略不允许该发送者发送。 |
12ReasonConnectKick | CONNECT / disconnect | 由应用策略决定 | 保留 | 保留的连接踢下线结果;当前产品路径未发出该值。 |
13ReasonNotInWhitelist | SEND | 修复请求后再操作 | 当前路径可达 | 频道启用白名单,而发送者不在其中。 |
14ReasonQueryTokenError | CONNECT | 有界退避重试 | 保留 | 保留的 Token 查询错误;当前默认组合未发出该值。 |
15ReasonSystemError | CONNECT / SEND | 有界退避重试 | 当前路径可达 | 服务端压力或内部错误;使用同一幂等键进行有界退避。 |
16ReasonChannelIDError | SEND | 修复请求后再操作 | 保留 | 保留的频道标识错误;当前产品路径使用其他错误映射。 |
17ReasonNodeMatchError | CONNECT / SEND | 刷新路由后复用幂等键 | 兼容路径 | 兼容节点匹配失败;刷新路由。 |
18ReasonNodeNotMatch | SEND | 刷新路由后复用幂等键 | 当前路径可达 | 当前节点不是新鲜权威目标;刷新路由并复用原幂等键。 |
19ReasonBan | CONNECT / SEND | 修复请求后再操作 | 当前路径可达 | 用户连接或频道发送已被封禁。 |
20ReasonNotSupportHeader | CONNECT / SEND | 修复请求后再操作 | 保留 | 保留的 Header 不支持结果;当前产品路径未发出该值。 |
21ReasonClientKeyIsEmpty | CONNECT | 修复请求后再操作 | 当前路径可达 | 需要客户端密钥的握手未提供密钥。 |
22ReasonRateLimit | CONNECT / SEND | 有界退避重试 | 兼容路径 | 客户端与压测器保留的限流结果;当前默认产品路径未发出该值。 |
23ReasonNotSupportChannelType | SEND | 修复请求后再操作 | 保留 | 保留的频道类型不支持结果;当前产品路径未发出该值。 |
24ReasonDisband | SEND | 修复请求后再操作 | 当前路径可达 | 频道已解散,不能继续发送。 |
25ReasonSendBan | SEND | 修复请求后再操作 | 当前路径可达 | 发送者被禁止发送。 |
26ReasonChannelDeleting | SEND | 有界退避重试 | 保留 | 保留的频道删除中结果;当前产品路径未发出该值。 |
27ReasonProtocolUpgradeRequired | CONNECT | 升级客户端后重试 | 兼容路径 | 网关保留该连接失败分类;当前默认认证路径未发出该值。 |
28ReasonIdempotencyConflict | SEND | 修复请求后再操作 | 保留 | 保留的幂等冲突结果;当前产品路径未发出该值。 |
29ReasonMessageSeqExhausted | SEND | 修复请求后再操作 | 保留 | 保留的消息序号耗尽结果;当前产品路径未发出该值。 |
前置条件
- 已记录出现该值的数据包类型,而不是只有一个裸数字;
- 已区分 HTTP 状态、CONNACK、SENDACK、在线投递和同步结果;
- 重试实现具有幂等标识、退避、次数上限和取消;
- 日志与指标会遮蔽身份和消息内容。
如何读表
- 阶段说明该值适用于 CONNECT/CONNACK、SEND/SENDACK、断开或兼容路径中的哪类上下文。
- 重试是安全默认,不是无限重试许可;必须结合幂等标识、退避、上限与取消。
- 可达性区分当前生产路径可产生、只在特定配置/状态下可产生,以及保留在兼容枚举但当前黄金路径没有证据的值。
- “枚举中存在”不等于每个端点或 SDK 调用都可能返回它。
客户端处理顺序
- 先记录包类型、Reason Code 数值、兼容快照和请求关联信息。
- 只有明确 Success 才完成当前协议阶段。
- 身份、权限、黑白名单、封禁、解散、无效字段或不支持结果应停止盲目重试。
- 路由变化、速率限制和系统错误只能采用有界指数退避,并在重试前重新发现必要状态。
- 未知数值按未知失败 fail closed;保留原值,不映射成 Success。
发送结果与消息阶段
对持久 SEND,成功 SENDACK 表示 Channel 权威已经作出持久提交成功决定。它不证明在线接收、RECVACK、Webhook、插件、离线同步或业务动作完成。
CONNACK 成功只表示当前 Gateway 连接阶段完成。默认 v3 Beta 组合尚未自动使用已存 Token 做 CONNECT 校验,因此不能把成功 CONNACK 描述为生产业务身份已验证。
预期结果
黄金样例会记录 SENDACK 的成功/失败状态和 message sequence;失败文本保留原始 Reason Code 数值,便于回到本表解释。事件日志不会显示 Token 或 Payload,产品 UI 应再映射自己的本地化业务文案。
失败诊断
- 值与名称不匹配:这是生成或版本漂移,必须让校验失败。
- 收到表中标为未在黄金路径验证的值:保留原始证据并报告源码 revision,不要更改可达性结论来迎合一次现象。
- 持续收到可重试结果:停止超过预算的重试,检查路由、限流、队列压力和集群状态。
- 权限类结果重试后仍失败:回到业务账号、membership、黑白名单或频道状态修正权威事实。
- 未知数值:按失败处理并升级兼容清单与字典校准。
安全与责任边界
Reason Code 不应泄露内部拓扑、风控判断或敏感身份。日志使用低基数字段,并将 UID、Token、Channel ID 与消息正文排除在指标标签之外。面向最终用户的文本由业务产品拥有。
下一步
回到错误响应组合 HTTP 与协议层处理,或按Quickstart观察 SENDACK 与同步恢复的区别。