Skip to content

晞晗IM(XHIM)兼容性策略

适用阶段:0.1 Commercial Beta

本文说明 XHIM 当前承诺保护的边界,以及接入方升级时必须遵守的规则。它不构成 特定版本的支持周期、平台认证清单或服务等级承诺;这些信息应由具体发行说明 单独给出。

1. 稳定性分层

层级当前状态兼容原则
xhim_v1_* C ABI稳定边界同一 ABI Major 内保持已发布符号、布局、调用约定和数值语义
Protobuf wire 字段稳定协议边界已发布字段号和 enum 数值不复用,删除字段必须 reserved
SQLite 数据内核拥有只允许内核迁移;不承诺表结构是业务查询 API
CMake 包 XHIM支持的接入入口XHIM::XHIM 指向稳定 C ABI;XHIM::Engine 等 C++ Target 按下条处理
C++ 模块接口0.x 实验扩展不承诺源码兼容、C++ ABI 兼容或类布局稳定
平台 Facade/UI Kit0.1 Commercial Beta源码 API 可试用;正式签名包发布前不承诺长期兼容

0.x 安装包生成的 XHIMConfigVersion.cmake 使用 SameMinorVersion。例如, find_package(XHIM 0.1 CONFIG REQUIRED) 可以接受符合 CMake 版本规则的 0.1.x,但不会自动接受 0.2.x;未写版本号时仍由下游自行承担选择结果。 这样可以避免实验性 C++ Target 在次版本调整后被静默替换。它不改变 xhim_v1 C ABI 的 generation 兼容承诺。

2. xhim_v1 C ABI

v1 表示 ABI generation,不等同于 SDK 的 0.x/1.x 产品版本。以下内容一旦 作为发行制品发布,就属于 xhim_v1 兼容合同:

  • xhim_v1_* 导出符号名称和 C 调用约定;
  • 公开结构体已发布字段的顺序、类型、对齐和含义;
  • 状态码、Client State 和 Event Kind 的数值;
  • Handle、Callback 和 byte view 的所有权与生命周期;
  • 异步 API 的立即返回值与 Completion 语义。

同一 ABI generation 内只允许可兼容扩展:

  • 新增导出函数;
  • 在带 struct_size 的结构体尾部增加可选字段;
  • 增加接收方能安全忽略的新状态或事件;
  • 修复不改变已承诺语义的实现缺陷。

调用方必须:

  • 创建公开结构体前清零内存;
  • 设置 struct_sizeabi_version
  • 不读取 struct_size 之外的尾部字段;
  • 忽略能够安全忽略的未知事件,并记录诊断;
  • 不依赖未写入文档的内部线程、时序或错误文本。

无法兼容的函数签名、结构布局、所有权或数值语义变化必须进入新的 ABI generation,例如 xhim_v2_*,不能静默改变 xhim_v1_*

正式 Android、Windows 和 Harmony 原生证明同时绑定 include/xhim/xhim_v1.h 的路径、大小与 SHA-256,并把它逐字节核对到发行 Commit 中的 ffi/include/xhim/xhim_v1.h Git blob。三端组包输出及统一客户 制品根会重复校验同一来源,避免“二进制属于目标 Commit,但公开结构体声明来自 另一提交”的 ABI 混装。

3. C++ 扩展接口

XHIM::EngineXHIM::CoreXHIM::StorageXHIM::SyncXHIM::ProtocolXHIM::TransportXHIM::MediaXHIM::RTC 方便后端 Adapter 和内核联合开发, 但在 0.x 阶段不是稳定 SDK ABI。安装包能够被 find_package(XHIM) 找到,并不 表示这些 C++ 类型具备跨版本二进制兼容性。

XHIM::Engine 当前暴露统一组合根 ClientEngine,以及深度定制所需的 SessionBackendMessageTransportFactory Port 和 SessionCoordinator 编排器。使用方应把 Backend 与 Transport Factory 的唯一所有权交给 ClientEngine::create(),不得在业务层另行拼装一套并行状态机。 SessionBackend 的请求/结果结构、虚函数表、RealtimeSession/ RealtimeEventSink 所有权、取消合同、Coordinator 构造参数、状态观察接口和 状态枚举,以及 report_session_fault 的 Runtime 应用 acknowledgement, 都属于 0.x 实验面。 product_adapter/include/ 下的 build-time SPI 同样不是安装接口或稳定 ABI; 它要求产品 Adapter 与指定 XHIM 源码、编译器和 C++ 标准库一起构建。稳定承诺 只覆盖最终制品仍然暴露的 xhim_v1 C ABI,不覆盖工厂函数或产品 OBJECT target。

这些接口可能在次版本升级中发生:

  • namespace、头文件位置或类型名称调整;
  • 构造参数、虚接口或错误模型变化;
  • STL 类型、类布局和编译选项变化;
  • Target 依赖关系调整。

当前 Engine 的安全状态语义是:只有 canonical 认证、完整且已经验证的 EndpointBundle、连接建立、顺序分页 Sync 原子提交以及到达 high watermark 全部成功后,Coordinator 才发布 Ready。这条语义用于避免部分登录被误认为 可用会话。Ready 后,WebSocket 事件只作为 Sync hint;断线会关闭当前 RealtimeSession、废弃 connection generation、有限重连,并在新连接上完成 恢复 Sync 后再回到 Ready。旧 relay/generation 的事件不得写库或复活会话。 这些生命周期状态已经通过稳定 xhim_v1 Event/State 数值映射暴露; xhim_v1_client_get_message 已形成按客户端消息 ID 查询的稳定 C ABI, xhim_v1_client_list_messages 已形成使用不透明 keyset Cursor 的会话时间线 分页边界,xhim_v1_client_list_conversations 已形成按置顶和持久化活动顺序 读取会话摘要的不透明 keyset 分页边界。会话偏好只使用 xhim_v1_conversation_snapshot_t 原先预留的两个 uint64_t 槽暴露 revision 和 flags,数组元素仍保持 112 字节步长;详细 mutation ID/更新时间由偏好操作的 独立 receipt 返回,不能通过扩大数组元素破坏旧客户端索引。 xhim_v1_client_mark_conversation_read 已形成服务端确认后才推进的单调已读 序号边界,并通过新增 Event Kind 5 通知会话摘要失效。该事件可被旧客户端安全 忽略;Protobuf CONVERSATION_READ_UPSERT = 7 则是不可跳过的持久状态事件, 不支持它的旧客户端必须升级而不能推进 Cursor。xhim_v1_client_send_message 已形成 通用版本化二进制消息信封发送边界;消息快照通过 struct_size 尾部扩展增加 content_type,旧接入方只读取既有前缀仍保持兼容;编辑/撤回 projection 则 复用消息快照原有两个预留槽表示 revision/kind,继续保持消息数组 192 字节 步长,不在数组元素后追加字段。

好友删除、退群和解散群通过新增 xhim_v1_client_delete_friendshipxhim_v1_client_leave_groupxhim_v1_client_dismiss_group 符号以及各自独立的 versioned Input/Result 结构加性进入 v1 ABI;既有枚举值、旧结构字段顺序和数组 stride 均未改变。 Input 以 struct_size + abi_version 探测已知前缀并在同步返回前深拷贝; Completion 中的 friendship、group change、members 和嵌套 byte view 只在回调 期间借用。退群/解散群的 expected_revision 是非零服务端 CAS,返回结果携带 idempotent_replay;未知尾字段和预留槽必须忽略并保持为零。三类 request ID 复用既有通用取消 ABI,不新增不兼容的取消枚举或句柄类型。

好友列表也是数组 ABI,既有 xhim_v1_friendship_snapshot_t 固定保持 64 字节 步长,不能为备注直接追加字段。定向备注通过独立 64 字节 xhim_v1_friendship_remark_snapshot_t 平行数组和 xhim_v1_social_page_get_friendship_remarks() 暴露;调用方按 friendship 数组的相同 index 关联,并只在 page 借用生命周期内读取。备注写入通过新增 xhim_v1_client_set_friend_remark()、独立 80 字节 versioned Input 和 160 字节 change snapshot 加性进入 v1 ABI。空备注表示显式清空而不是“缺少字段”, 其非零 revision 必须保留;inactive friendship 则必须同时清空备注并归零 revision。

群列表同样是数组 ABI,xhim_v1_group_snapshot_t 固定保持 112 字节和原有 字段顺序。新增的群名称、头像 URL、群资料 revision 不会直接追加到该数组元素; 它们由独立 88 字节 xhim_v1_group_profile_snapshot_t 平行数组提供,并通过 xhim_v1_social_page_get_group_profiles() 在 page 生命周期内读取。调用方必须 按群数组的相同 index 关联两者;函数返回不支持、kind 不匹配、数量不一致或 空 Profile 时,应保留群基础记录并把资料当作暂不可用,不能自行改变旧 xhim_v1_group_snapshot_t 的 stride。

媒体描述已固定独立的 xhim.protocol.media.v1 Protobuf 身份与字段号。稳定 C ABI 已追加媒体任务 upload/download create、get/cancel、scoped media-cache reader、 xhim_v1_media_task_snapshot_t@1XHIM_V1_EVENT_MEDIA_TASK_UPDATED@1; 旧 Event 结构前缀保持不变,新尾部用 struct_size 探测。未知媒体状态数值必须作为前向状态保留并重新查询,不能映射 为失败。xhim_v1_client_get_diagnosticsxhim_v1_diagnostics_snapshot_t@1 是加性的同步只读边界;调用方按 schema_version 解析已知字段,并忽略未来新增尾字段,不能依赖瞬时队列深度 保持不变。Diagnostics 与同步 OfflineReader page 的 struct_size 是调用方输入 容量,Core 只做有界前缀写入并保留容量值。xhim_v1_client_notify_network_available 是加性的同步无回调提示; 旧客户端不调用时仍由原有的有限重连定时器保底。C++ MediaTransport/处理器/ Worker 和 XHIM::RTC 的 Call Actor/Provider SPI 仍属于 Developer Preview C++ 扩展面;媒体任务的 持久受理、查询、取消、失效事件和无路径缓存读取已经进入稳定 C ABI,但具体 对象存储、审核/CDN 以及 RTC Provider 仍是产品 Adapter 或未来可选扩展,不属于 稳定公共 ABI。

深度定制方应锁定明确的 XHIM 版本,在自己的 Adapter 上运行编译和集成测试, 并把对业务层的长期稳定接口放在 xhim_v1 C ABI 或自己的平台 Facade 上。 不要跨不同编译器、C++ 标准库或运行时直接交换 XHIM C++ 对象。

当前仓库已经提供连接 XHIM Go 参考服务端的真实 SessionBackend/Transport Product Adapter,并由 build-time 工厂注入 ClientEngine/ SessionCoordinator 生产路径。默认通用构建仍 fail closed,产品发行必须 显式选择并固定自己的 Adapter、信任根和部署端点;Fake Backend、本地 preview 或仅通过参考环境测试仍不构成生产兼容、生产可用或服务 等级承诺。实验接入和生命周期要求见 XHIM 接入指南

4. 协议兼容

  • Protobuf 字段号和 enum 数值一经发布不得改变语义或复用。
  • 删除字段时必须同时保留其原编号和原名称为 reserved
  • 新事件必须定义旧客户端的跳过或升级要求,不能依赖未知字段自动等价于兼容。
  • Cursor、Hash 和不透明 Payload 必须按字节保存和回传,不能自行解析或重写。
  • 更改 Protobuf package、消息全限定名或 Any type URL 属于协议身份变化,必须 在发布前完成,或通过明确的新协议版本迁移。

仓库已经绑定可运行的 XHIM Go 参考服务端和 Reference/Apple Product Adapter; 这只定义参考产品合同,不代表任意客户部署已经完成生产验收。最低客户端版本、 能力协商和协议停用策略必须由最终部署的服务端与发行包共同配置,不能仅由客户端 猜测。

5. 数据库和升级

SQLite 数据库是 XHIM 的私有持久化格式,不是公共业务数据库 API。

  • 接入方不得直接修改表、索引、Trigger、PRAGMA user_version 或 metadata。
  • 升级只能由新版内核执行其内置迁移。
  • 数据库迁移成功后,不保证旧版内核能够降级打开。
  • 多账号必须使用隔离的数据库路径。
  • 升级前应停止旧 Client,确保没有另一个进程或旧版本仍在访问同一数据库。
  • 正式发布流程应在可恢复环境验证迁移,并按宿主的数据保护策略完成备份或 回滚准备。

内部保留 ID、幂等键和已持久化 identity 不能因品牌、日志格式或实现重构而 直接复用。若新版本引入新前缀,必须继续识别并保护已经发布的旧前缀。

6. 升级原则

  1. 阅读目标版本发行说明,确认 ABI generation、数据库迁移和协议要求。
  2. 在独立构建和测试环境升级 CMake package,不复用旧版生成目录或安装目录。
  3. 对 shared/static、目标平台架构、账号登录、发送重试、Sync 和旧库迁移执行 回归测试。
  4. 平台 Wrapper 在加载内核后校验 ABI 版本和运行时版本字符串。
  5. 先停止并销毁旧 Client,再替换内核和启动新版;不要让两个版本同时访问同一 storage profile。
  6. 如果升级要求新的 ABI generation,平台 Facade 必须显式适配,不能依赖符号 名碰巧相同。

0.x 表示产品能力仍在快速建设,不表示可以忽略上述兼容边界。若安全性、数据 完整性或协议正确性要求不兼容修复,项目必须在发行说明中明确标出影响和迁移 方式,而不能把破坏性变化伪装成普通补丁。

接入步骤见 XHIM 接入指南

XHIM 客户端 SDK 与服务端文档