SuperAPI AI 工具集

server-default-overrides-client-intent

编程与开发

查看项目

更新于 10-17 16:17

技能介绍

用途

这条记录面向实现或维护 Kotlin 会话客户端(源端与跟随端)的开发者,说明一个跨端状态同步陷阱:持有共享会话状态的中继(relay)在转发命令时会补齐所有字段,未设置的字段取中继默认值。对于表示运行/暂停的标志,该默认值几乎总是 false,因此一条只改条目的命令到达每个跟随端时都带着“未运行”。

问题表现

跟随端若照单全收,就会加载新条目后停止播放。这看起来像客户端 bug,实际是协议默认值造成的。源端本地状态在“一个运行条目接另一个运行条目”时不会发生变化,没有状态迁移、没有发射、没有发布者触发,所以源端不会自动补发缺失字段,现象只在其他成员设备上出现,单设备测试无法复现。

主要补偿方式

接收侧:仅在“条目发生变化且传入标志处于中继默认值”时,改用会话最近一次意图作为运行状态;其余情况照传入值处理。该值需在每条已应用命令上更新(包括暂停),且要写入解析后的结果而非传入字段;离开会话时清除,避免影响下一个加入的会话。

发布侧:条目变更后单独发送一条运行/暂停状态命令,因为条目变更命令中没有中继会保留的对应字段。推送完整快照(接任源端、新成员加入)时同样需要两条命令,否则会话会被宣告为“已播但暂停”。

限制与陷阱

  • 覆盖条件必须收窄:只判断条目变化会忽略真实暂停,只判断标志默认值会把“下一条暂停”覆盖为继续播放。
  • 携带值只在条目变化时更新会过期,经历一次暂停/恢复后就失真。
  • 写入传入值而非解析结果会让补偿变成一次性。
  • 未发送的集合、标题、位置等字段也会取默认值;一般应将缺省视为“无需表态”,保留原值而非清空。
  • 中继可能因运行/暂停命令携带的条目 id 已非当前条目而将其静默丢弃;这可作为假设,文中建议在协议允许时发送空 id,由中继填入当前条目。
  • 不应修改中继:线路格式与对端实现不归自己所有时,单方面“更干净”的默认值会破坏互操作,补偿应放在客户端。
  • 即使自己的两个客户端已正确互通,跟随端的携带逻辑仍不可省略,因为会话中可能还有不了解该缺失字段的客户端。
  • 运行标志应在加载之前只解析一次,供加载与传输两步共用,避免两处条件发散。

验证方式

文中给出两条 grep 检查:一条查找携带意图字段并确认其在每条已应用命令上写入;另一条在条目变更路径附近(约 40 行窗口)查找 PLAY/PAUSE 命令,确认每个变更点之后都有第二条命令,无命中则说明发布路径未做补偿。行为验证需要两个客户端和三种独立转换:源端上一首/下一首(跟随端须持续播放)、条目自然结束自动前进、条目变更后立即真实暂停(跟随端必须暂停;若此例失败说明覆盖过宽)。