Skip to content

晞晗IM(XHIM)平台 Facade 维护指南

适用版本:0.1 Commercial Beta

文档职责:供 XHIM SDK 发行人员维护 C ABI、平台 Facade、线程、内存和发布 边界。普通 App 开发者请直接阅读客户端 SDK 接入总览

客户端开发者不需要安装 Docker、初始化数据库、配置服务端密钥或执行服务端 脚本。开始接入前,只向服务端负责人领取 Server URL、测试 User ID 和测试 Conversation ID。

0. 第一次接入:不要从 C++ 或 C ABI 开始

如果你的目标是在一个空白 App 中加入晞晗IM,请直接选择你的客户端平台:

你正在开发从零接入文档UI 包当前可验证程度
iOSiOS 空白工程快速接入 / CocoaPodsXHIMSwiftUIDevelopment XCFramework 已完成真机 + Server 联调
macOSmacOS 空白工程快速接入XHIMSwiftUIFacade/UI 与运行时配置已完成;正式 slice 待发行机生成
AndroidAndroid 空白工程快速接入xhim-ui-composeFacade、媒体上传、系统 Picker 已完成;正式 AAR 待发行机生成
WindowsWindows 空白工程快速接入XHIM.UI.WpfFacade、媒体上传、WPF Picker 已完成;签名 NuGet 待 Windows 发行机生成
HarmonyOSHarmonyOS 空白工程快速接入ArkUI 组件Facade、媒体消息、系统 Picker 已完成;正式 HAR 待 DevEco 发行机生成

五个客户端终端已提供同一语义的平台原生一键入口:

text
新建空白工程
  → 添加平台包
  → 填写 Server IP/域名和 User ID
  → 平台 connect API 自动发现部署、创建存储、启动和登录
  → 把 Facade 数据映射给可选 UI Kit
  → Alice/Bob 两端互发
  → 按上线清单移除开发配置

不要把 X-XHIM-Admin-Key、JWT 签名私钥或数据库密钥放进客户端。 Development Server 可以显式开启仅凭已创建 User ID 的 Easy Login;Production 会拒绝该开关。正式 App 只在账号容器提供一次业务凭证闭包,SDK 自动初次获取和 过期续期,页面与普通业务代码不处理 Token。UI Kit 也是可选层;不使用 XHIM 默认页面时,Headless SDK 仍可独立完成登录、收发、同步、分页和已读。

各平台 QuickStart 均从空白工程开始,并使用 XHIMClient.connect(iOS/macOS/Android/HarmonyOS)或 XHIMClient.ConnectAsync(Windows)完成发现、账号隔离存储、登录和自动续凭。 iOS 可通过 CocoaPods/SwiftPM,Android 通过 Maven/AAR,Windows 通过 NuGet, HarmonyOS 通过 OHPM/HAR 接入。普通 App 开发者到对应 QuickStart 即可;只有 XHIM 产品构建人员才继续阅读本页后面的 Adapter、C ABI 和发布边界。

0.1 文档结构基线

快速文档的组织方式参考了主流 IM 厂商当前官方教程中已经被开发者验证的共同 路径,而不是复制其 API:

XHIM 在此基础上增加了私有化 Server、隐藏凭证生命周期的一键登录、可靠 Outbox、服务端序号、 数据库加密、五端签名制品和上线安全检查。任何快速示例都不能为了“几行跑通” 把 Admin Secret 放进 App。

1. 客户端团队可以依赖什么

正式商业交付目标包含:

  • 对应平台的二进制 SDK 包,不要求 App 编译 C++ 源码;
  • 平台原生 Facade、异步 API、事件流和稳定错误类型;
  • 可选 UI Kit、系统相机/相册/视频/文件选择器和媒体消息接口;
  • 账号隔离存储、可靠 Outbox、断网恢复、分页同步和已读能力;
  • 由服务端负责人交付后可直接填写的 Server URL;
  • 不同平台分别提供的空白工程 QuickStart 和上线检查。

当前仓库是 Commercial Beta:已有受控 Apple Development 包;macOS 正式 slice、AAR/Maven、NuGet 和 HAR 的源码/Bridge/组包门禁已验证,但最终签名 二进制仍须由相应发行机生成并通过 clean-consumer 与真机矩阵。不能把源码构建 通过写成客户已经拿到正式制品。

客户端项目不实现 Backend、不直接操作 SQLite,也不持有服务端管理凭证。SDK 内核构建、服务端实现、部署验证和发行门禁不属于客户端接入步骤。

2. 按平台选择指南

平台正式目标产物原生入口当前指南
iOSXCFramework + Swift Package / CocoaPods回调式 API、Swift async/await、AsyncStreamiOS 接入指南
macOSXCFramework + Swift Package回调式 API、Swift async/await、AsyncStreammacOS 接入指南
AndroidAAR + Maven 元数据Kotlin coroutine、FlowAndroid 接入指南
Windowsx64/arm64 DLL + NuGetC# Task、IAsyncEnumerable、SafeHandleWindows 接入指南
HarmonyOS / OpenHarmonyarm64-v8a .so + HAR/OHPMArkTS Promise、异步迭代/订阅HarmonyOS 接入指南

四份平台指南都按同一顺序说明:

  1. 当前状态与客户可依赖的边界;
  2. 商用包必须包含的文件;
  3. 从源码验证内核的方式;
  4. 原生 Facade 应如何封装 C ABI;
  5. 生命周期、线程、Callback 和内存规则;
  6. 账号存储、后台、附件媒体与可选 RTC 平台要求;
  7. UI Kit 分层和二次开发边界;
  8. 发布前验收清单。

3. 所有平台共同遵守的稳定边界

普通平台 Wrapper 只调用:

text
XHIM::XHIM
└── <xhim/xhim_v1.h>
    └── xhim_v1_* C ABI

XHIM::EngineXHIM::StorageXHIM::SyncXHIM::TransportXHIM::MediaXHIM::RTC 是产品 Adapter 与内核联合开发接口。它们包含 C++ 类型、STL、 虚函数表和类布局,在 0.x 阶段不承诺 C++ ABI 兼容,不能暴露给 Swift、Kotlin、 C# 或 ArkTS 业务代码。

平台 Facade 必须把 C ABI 转换为本平台习惯的类型:

C ABI平台 Facade
xhim_v1_client_t *单一所有权 Client 对象
xhim_v1_subscription_t *可取消订阅/Token
立即 int32_t 返回值同步参数或准入错误
Completion Callbackasync/await、Task 或 Promise
Event CallbackAsyncStream、Flow、事件流或订阅
xhim_v1_bytes_view_tCallback 内立即复制的 Data/ByteArray/byte[]/ArrayBuffer
xhim_v1_error_t平台稳定错误类型,完整保留下表中的机器可判定字段

错误字段的职责固定如下,宿主不得解析 message 文本来决定业务分支:

字段用途
codeABI 级粗粒度状态,兼容既有调用方
domain + stable_code跨语言、跨版本的业务判断键
native_code服务端、系统或传输层原始错误码
retryable + retry_after_ms是否可重试以及最早重试时间
user_actionRETRY/UPDATE_CREDENTIAL/CHECK_NETWORK/CONTACT_SUPPORT 等稳定建议
operation_id + trace_id单次 SDK 操作和服务端链路定位
message面向开发者的诊断文本,不作为稳定合同

新增字段位于 xhim_v1_error_t 的兼容尾部;Bridge 必须先检查 struct_size 再读取尾部字段。旧 Wrapper 仍可按原结构前缀工作,新 Wrapper 必须复制全部字段并映射为平台原生 Error/Exception。

4. 公共生命周期

每个平台都必须维持同一条生命周期:

text
create → start → login → Ready → use
                    │          ↓
                    │  logout → login
                    │          ↓
                    └→ CredentialRequired
                               ↓ updateCredential(new token)
                              Ready

任意可运行状态 → shutdown → destroy/dispose
  • create 同步复制 app_idstorage_path,并打开/迁移数据库;
  • start 启动内核,但不等于登录;
  • login(account_hint, access_token) 的 hint 只用于路由,账号最终以服务端认证 返回的 canonical account_id/self_user_id 为准;
  • 认证过期进入 CREDENTIAL_REQUIRED 后调用 update_credential(access_token); Core 继续使用当前 canonical account,宿主不得重新传入或替换账号 ID;
  • 只有状态到达 READY 后才能发送和读取当前公开的消息/会话 API;
  • logout 允许同一 Client 再次登录;shutdown 是不可逆终止;
  • 最终销毁必须与其他 Client API 外部串行化;
  • 一个 Client 同时只绑定一个账号,多账号必须使用不同 Client 和不同数据库路径。
  • 版本化运行策略在 create 时复制,统一控制请求超时、Sync Page 和有限重连; 账号生命周期内不可变,四套原生 Facade(覆盖五端)均先做范围校验;
  • 客户部署可在 create 时设置 Bootstrap URL、Endpoint Key ID 和 Ed25519 公钥;三者必须同时出现并由 Facade 复制。它们属于部署配置,不是每次请求可变 参数。API/WSS/上传/下载地址只能来自验签且未过期的 EndpointBundle;
  • TLS Trust 和生产能力开关不接受业务代码动态关闭,Product Adapter 必须 fail closed。

生产配置必须保持 flags == 0XHIM_V1_CLIENT_FLAG_LOCAL_PREVIEW 只用于仓库 CLI 和自动化测试;正式制品应设置 -DXHIM_ENABLE_LOCAL_PREVIEW=OFF

5. Callback、线程和内存

  • 同一 Client 的 Event 和 Completion 在 XHIM 私有串行 Callback 线程执行, 不保证是 UI/Main 线程;
  • Wrapper 必须在 Callback 内复制所有 byte view,再切换到 UI/Main 线程;
  • Callback 可以提交新的异步请求,但不能同步等待另一个 XHIM Callback;
  • Wrapper 负责让传入 C 的 callback context 在取消或最终 Callback 完成前存活;
  • subscription_cancel 对同一 handle 只能调用一次,且不能并发调用;
  • client_destroy 开始后不得再调用任何 Client API;
  • 平台对象析构、GC/finalizer 或 ArkTS 回收钩子只能作为泄漏兜底,业务必须提供 明确的 close/dispose/shutdown

6. 消息、分页和媒体

  • send_texttext/plain@1 的便捷入口;
  • 其他消息使用不可变 content_type + content_version + payload + fallback_text
  • iOS/macOS/Android/Windows/HarmonyOS 均提供 XHIMMessagePluginRegistry(使用 各自语言命名风格)和 UI Renderer Registry。发送自定义消息前先注册并校验, 接收后由插件生成会话/通知摘要;未知类型、高版本或插件异常必须使用 fallback_text,不得丢弃原始 Payload 或阻塞 Cursor;
  • client_message_id 在一个 storage profile 内全局唯一;重试同一逻辑消息必须 复用同一 ID 和相同 Payload;
  • retry_message(client_message_id) 只重新入队当前账号下的永久失败消息,并 原样复用已持久化信封;对已经在 Pending/Retrying 的同一请求幂等成功;
  • cancel_message(client_message_id) 只取消尚未被 Transport 获取的本地 Pending/Retrying/Failed 工作;对已经 Cancelled 的消息幂等成功,对 Sending 或 ServerAccepted 明确返回冲突/忙碌,不能声称撤回了已发送消息;
  • Retry/Cancel 在 Runtime actor 内执行,并受当前账号 Epoch fence 保护; 只有状态实际改变时才发布 MESSAGE_RETRY_QUEUED/MESSAGE_CANCELLED 事件;
  • 分页 Cursor 是账号/查询范围内的不透明二进制值,可能包含 NUL,平台层只能 原样复制和回传;
  • Callback 返回的消息和会话数组都是借用内存,必须在 Callback 返回前深拷贝;
  • 媒体 Payload 只保存稳定 MediaRef,不能放原始文件、本地 URI、Token 或 临时签名 URL;
  • iOS、macOS、Android、Windows 和 HarmonyOS 的默认发送路径均创建 Core-owned durable media task,由内核持久化进度、恢复、校验并在 Ready 后写入稳定 MediaRef;旧 XHIMMediaUploader SPI 只保留兼容迁移和特殊客户扩展;
  • SwiftUI、Compose、WPF 和 ArkUI 均提供系统相机/相册/视频/文件入口。Picker 只返回宿主可读的本地 URI/URL,不在 UI 层上传;ViewModel 将其交给 sendImagesendVideosendAudiosendFile 创建持久媒体任务;
  • 实时通话不属于纯 IM 首发范围;以后通过独立 Call/RTC Provider 可选包接入, 不走普通消息 Outbox,也不修改消息内核。

xhim_v1_client_mark_conversation_read() 已提供服务端权威的跨设备已读。 调用方应在聊天页已经展示服务端确认消息后,取其中最大的正 server_seq, 连同会话 ID 提交;本地 Pending/Sending 消息没有服务端序号,不能作为已读 目标。Core 会先确认目标序号已经存在于当前账号的本地时间线,再请求服务端, 只有服务端回包成功后才原子更新 SQLite 的 read_seq/unread_count,不做乐观 清零。

服务端按 (app_id, conversation_id, user_id) 保存单调 read sequence,并把 变更作为不可跳过的账号 Sync 事件投递给当前用户的其他设备。同值或更低值是 成功 no-op,不重复发布变更事件;高于服务端会话最新序号、非会话成员或跨账号 请求必须拒绝。Completion 返回服务端确认的会话 ID、已读序号、剩余未读数和 更新时间;CONVERSATION_READ_CHANGED 只携带会话 ID,UI 收到后应重新读取 该会话摘要,而不是自行推算未读数。iOS、macOS、Android、Windows 和 HarmonyOS 的 对应原生方法与线程规则见各平台接入文档。

附件媒体和未来可选 RTC 的完整边界见 商用媒体消息与实时音视频架构

服务端社交协议位于 protocol/proto/xhim_social_v1.proto,包括好友申请、 接受/拒绝、社交快照、建群、带 expected_revision 的成员增删和成员分页。 所有成功变更与账号事件流在同一服务端事务提交,WebSocket 仍只发送 Sync Hint; 客户端必须通过 /v1/sync 拉取权威事件,不能把 Hint 当作业务数据。

当前 C++ xhim_v1 已暴露好友申请、好友、群、群成员、黑名单和入群申请的 稳定分页查询,并通过 Schema v12 写入账号隔离的本地 SQLite 投影;iOS、macOS、 Android、Windows 和 HarmonyOS 在线 Client 与 OfflineReader 已提供对应的 强类型分页。后续增量 API 仍必须直接复制这些 C ABI 页面,不能绕过 Core 自建长期关系缓存。

7. 存储路径和安全

平台层必须把数据库放在应用私有、可写且不会被系统临时清理的目录。不要使用 Bundle/安装目录、共享 Downloads、外置公共目录或 Cache 目录作为主数据库。

建议路径语义:

text
<app-private>/xhim/<app-id>/<account-profile>/xhim.sqlite3

account-profile 应使用不可逆或服务端分配的不透明目录名,不要直接使用手机号、 邮箱或 Token。Token、数据库密钥、媒体密钥和日志脱敏策略由平台安全存储层负责。 同一数据库不得由多个进程、两个 Client 或不兼容 SDK 版本并发打开。

8. UI Kit 和二次开发边界

商业包应拆成两个可独立依赖的产品:

text
XHIM Headless Facade
├── 生命周期、账号、会话、消息、附件媒体 API
├── 自定义消息插件、摘要和版本兼容
└── 平台原生模型和事件流

XHIM UI Kit(可选)
├── 会话列表
├── 聊天页和消息 Cell/Renderer
├── 联系人、群组和搜索
└── 图片/文件组件

XHIM Call Kit(未来可选)
└── 厂商 RTC Provider、通话 UI 与系统通话桥

UI Kit 只能依赖 Headless Facade,不能直接调用 C ABI、打开 SQLite 或持有 C++ 对象。二次开发通过主题 Token、自定义消息 Renderer、动作拦截、页面路由和资源 Provider 扩展;删除 UI Kit 后,Headless SDK 必须仍然完整可用。

9. 产品构建团队入口

需要实现真实认证、HTTP/WSS、Codec、对象存储或未来 RTC Provider 时,阅读:

不要在 iOS、macOS、Android、Windows、HarmonyOS 五个原生 OS 的 Wrapper 中 各写一套登录、重连、Sync、Outbox 或媒体状态机。Swift 实现可以在 iOS/macOS 间复用,但两个客户入口和验收矩阵必须独立。平台层只处理语言绑定、平台生命周期、 系统能力和 UI;跨平台业务状态必须回到唯一的 C++ Core。

10. 客户项目验收

每个对外发布的平台包至少通过:

  • 空白项目只依赖最终发布包,不引用 XHIM 源码即可编译运行;
  • 加载后校验 xhim_v1_abi_version() == XHIM_V1_ABI_VERSION
  • 错误 Token 不进入 Ready,未配置 Backend 明确 fail closed;
  • 登录、发送、本地查询、分页、logout、换号和 shutdown 生命周期完整;
  • Callback 不在 UI 线程时,Facade 正确切线程且无借用内存越界;
  • 进程重启、升级迁移、断网、弱网、后台恢复和磁盘不足有确定结果;
  • 包含版本、Commit SHA、支持矩阵、符号文件、Hash、许可证、NOTICE 和 SBOM;
  • UI Kit 可选卸载,自定义 Renderer 和主题不会修改内核数据。

客户端验收只使用最终平台制品和服务端负责人交付的测试环境,不执行内核或 服务端构建脚本。服务端与 SDK 发行团队各自按照对应文档完成自己的验收,不能 代替五个平台最终制品、应用商店环境和真机验收。

XHIM 客户端 SDK 与服务端文档