C04 多设备能力收口

C04 对应“多端在线 / 多设备消息同步”能力。rev25 补齐了设备级投递游标与离线补收:Web/Electron/Android/Flutter 四端 SDK 自动生成并持久化 deviceId,服务端按设备独立记录 deliveredSeq。本页汇总能力、平台状态、证据、验收清单与剩余边界。

矩阵状态(Lead 汇总)

缺口矩阵:C04-web / C04-electron / C04-android / C04-flutter 已置 implemented;C04-native 仍 partial;C04-ios / C04-harmony missing(reserved)。

总计:382 implemented / 125 partial / 59 missing / 11 na / 14 excluded(591 行,由 Lead 更新,文档不改矩阵)。

能力清单与证据​

能力实现证据
多端同时在线同一 userId 允许多条 WS 会话;新连接不踢旧连接;消息扇出到全部在线端服务端 online 列表 + 投递路径
稳定设备标识各端 SDK 首次生成随机 deviceId 并持久化,重连/重启复用;业务无需传入Web localStorage;Electron device.json;Android ImStore;Flutter device storage
WS query 与 helloWS 可选 deviceId(≤128,超长拒绝握手);hello 回显并在 syncState 返回该设备 deliveredSeqIDL rev25;服务端 rev25
每设备投递游标{app}:{user}:{device}:{conv} 记录最大已 ack seq;A ack 不推进 Brev25 单测(两设备隔离/legacy 隔离/重连持久化)
每设备离线补收hello 后按该设备游标补发未 ack 消息,最后 sync_done;受每会话 500 条上限rev25 单测(新设备全量/重连不重复)
read / read_receipt 推进设备游标已读后重连不再补收已读消息;回执同样推进当前设备游标rev25 单测(read / read_receipt)
legacy 兼容无 deviceId 的旧客户端继续用用户级游标,行为不变rev25 单测(legacy ack 与 device ack 独立)
两阶段冒烟27 项多设备冒烟(设备 A/B 隔离、新设备、重连、legacy)服务端 181 tests + 冒烟

平台状态​

平台状态说明
Web / Electron / Android / Flutter✅ implementedSDK 自动生成并持久化 deviceId、建连携带、hello 回显处理;测试:Web v32 22/0、Electron 100、Android 402、Flutter 146+60
Native(C ABI)🟡 partialC ABI 无 deviceId/游标控制;离线补发按用户游标(等价 legacy),无跨端设备隔离
iOS / HarmonyOS⛔ missing(reserved)声明同构、无运行时代码

验收清单​

  1. 同一账号同 Token 建两条 WS(两条不同 deviceId)→ 都收到 hello,且 hello.deviceId 与各自 query 一致。
  2. A 设备 ack 一条消息 → B 断开重连 → B 仍补收该消息(A ack 不影响 B)。
  3. B 设备持续在线并 ack → 断开重连 → 不再重复补收已 ack 消息(游标持久化)。
  4. 新 deviceId 首次连接 → 收到全部未 ack 消息(≤每会话 500 条);超过时用历史分页补齐。
  5. 同一客户端断线重连复用同一 deviceId(不因重连生成新设备)。
  6. 旧客户端(不带 deviceId)与新版并存:legacy 游标独立推进,行为与升级前一致。
  7. deviceId >128 字符 → 握手被拒绝(HTTP 400/1001);空白视为未提供。
  8. read 会话后再重连:不再补收已读消息;其他设备未读行为保持用户级(已知限制)。

剩余边界​

项现状
端级未读 / 端级已读明细未实现:未读与已读回执仍按用户聚合(read 会清用户级未读)
设备凭证deviceId 是客户端自报,无设备级鉴权
Native / iOS / HarmonyOS 运行时C ABI 无设备游标;iOS/Harmony 无运行时
任务栏/角标按端未实现(依赖端级未读)
设备管理页未提供设备列表/下线接口(deviceId 仅用于游标)

相关链接​