好的实现不会依赖用户反复刷新碰运气,而会让每个阶段有明确输入、输出、超时和终态。 版本不是比较大小后选最大,因为不同分支可能不兼容。双方发送有序 supported set 和 feature constraints,按共同规则选一项。
API 契约不仅是字段类型,还包括单位、缺省语义、幂等性、错误分类和版本窗口。客户端必须能区分可重试、需用户操作与永久拒绝,避免统一重试制造副作用。
先定义系统契约
先从数据和协议能保证的事实出发,再决定界面承诺。下面的规则都应有明确所有者、边界值和兼容策略,不能只存在于某次代码评审的口头共识里。
- Hello 包含 protocolVersions、features、requiredFeatures 和 implementation limits;选中结果被双方签名或绑定会话,功能层只读协商快照。
- 先定义正常、降级、取消和失败四类终态,再让界面、存储与指标消费同一状态。
- 重试必须带幂等键、退避和截止时间;超过截止时间后建立新任务,而不是继续复活旧回调。
“协议版本协商:连接成功之前先确认双方真的能互通”的交付标准是正常路径可用、异常路径收敛、资源有界,并且用户能理解系统为何采用当前状态。 这样得到的不是演示代码,而是能解释、能降级、能回滚的生产能力。
哪些情况会破坏契约
最值得优先排查的是会静默留下错误事实的故障:界面看似恢复,底层队列、权限或计数却已分叉。这类问题通常在下一次动作才暴露。
- 每个功能自行猜对端支持会产生不同结论;收到未知高版本仍继续可能把取消或权限消息误解析成普通数据。
- 失败被压成一个布尔值,调用方无法区分可重试、需用户介入与永久拒绝,最终形成无限循环。
- 指标标签直接包含用户或任务标识,既制造高基数成本,也让诊断数据泄露不必要的身份信息。
如何逐条验证契约
验证时同时观察两端状态、持久化记录和可观测指标。单看某个按钮或一次接口响应,无法证明整个闭环成立。
- 生成所有当前、上一和未来未知版本组合,验证选择对称、必需能力拒绝清楚、降级功能隐藏且不会重复协商。
- 连续执行一百次开始、失败、重试和取消,检查句柄、监听器、队列及临时数据回到基线。
- 分别覆盖直连、中转、弱网、后台标签页和移动端,报告不能只给平均值或一次成功截图。
最终结果应同时满足正确性、可恢复性和可解释性。任何一项只能依赖刷新页面或工程师猜测,都说明协议闭环仍不完整。