宿主要接的那几件事
SDK 大部分能力是你主动调用它。但有几件事反过来:核心拿不到,只能由宿主 (你的 App)告诉它。这几个方法都标记为 stable,此前官网没有文档—— 不知道它们存在,接入就会缺一块,而缺的这块通常表现为「偶发的连不上 / 启动慢 / 消息里名字头像是空的」,很难往这个方向排查。
网络切换:client.connection.notifyNetworkChange
核心不监听系统网络事件——那是平台 API,各端不同,塞进核心就得写四遍。 宿主拿到网络变化时喂给它:
// iOS: NWPathMonitor / Android: ConnectivityManager / Web: navigator.onLine
client.connection.notifyNetworkChange({
available: true,
interface: 'wifi', // 'wifi' | 'cellular' | ...
expensive: false,
metered: false,
reason: 'path satisfied', // 仅用于诊断日志
})
不喂的后果是:断网后核心只能等 TCP/心跳超时才察觉,重连比实际可能的时机晚 几十秒。喂了它才能在网络刚恢复时立刻重连。
字段都是可选的:available 省略视为可用;不确定的项不必硬填。
启动首屏:client.sync.bootstrapStartupHome
冷启动时一次性把「首屏要显示的会话」拉齐,而不是等各个模块各自同步:
const res = await client.sync.bootstrapStartupHome({
conversationLimit: 20,
startBackgroundConvergence: true, // 首屏拿到后,后台继续补齐其余
backfillVisibleHistories: true, // 顺带预取可见会话的少量历史
historyBackfillLimit: 20,
historyBackfillMaxPagesPerConversation: 1,
historyBackfillMaxConversations: 8,
})
if (res.degradedReason) {
// 降级了(例如网络差、冷同步未完成):首屏可能不全,
// 此时该显示本地缓存而不是空列表
console.warn('startup degraded:', res.degradedReason)
}
返回里 coldSyncPerformed 与 backgroundConvergenceStarted 告诉你这次是冷同步 还是走了缓存,便于埋点对比启动耗时。
身份显示:client.user.upsertUserProfiles
开源栈不含账号体系,所以核心不知道用户叫什么、头像是什么。消息里的 昵称与头像由你喂进来,核心负责缓存与批量 join:
await client.user.upsertUserProfiles({
profiles: [
{ userId: 'u_1001', nickname: '张三', avatarUrl: 'https://.../a.png' },
{ userId: 'u_1002', nickname: '李四', avatarUrl: 'https://.../b.png' },
],
})
不喂的话消息能收发、顺序也对,但列表里是一片空白的名字与头像—— 这是「开源部分不含账号体系」在 UI 上最直接的体现。
自签 token:client.generateCoreToken
评估阶段用它签一个能连上网关的 token,不需要任何用户体系:
const { token } = await client.generateCoreToken({
userId: 'alice',
secret: gatewaySecret, // 与网关 token_secret 相同
issuer: 'flare-im-core', // 与网关 token_issuer 相同
ttlSecs: 3600,
})
secret 或 issuer 与网关不一致时,握手会被拒——而客户端看到的往往只是 「连接超时」。这是接入阶段最常见的一个坑,值得先核对这两项。
生产环境不要用它:密钥出现在客户端等于人人可签任意身份。 生产应由你的服务端签发,或走 Hook 校验。
诊断:client.diagnostics
排障时用,不参与业务:
| 方法 | 用途 |
|---|---|
getRuntimeHealth | 当前连接状态、会话代数、被丢弃的事件计数 |
getDataRoot | 本地存储位置,排查「数据去哪了」 |
getFfiContractVersion | 原生桥接的契约版本,排查版本错配 |
getRuntimeHealth 里的 rawSubscriberDroppedTotal 值得关注:它不为 0 说明 事件队列曾满而丢过事件,通常意味着上层消费太慢。
生命周期:uninit / hardReset
uninit:释放 SDK 占用的资源。切换账号或退出登录时调用。hardReset:清空本地状态重来。仅用于「本地数据疑似损坏」的兜底, 它会丢弃本地缓存,不要当成常规的登出。
心跳(一般不用改)
setHeartbeatNatTimeout 与 heartbeatEffectiveInterval 用于适配特定网络环境下 NAT 的空闲回收时间。默认值适用于绝大多数场景,只有在「链路总是被中间设备掐断」 时才需要按实测的 NAT 空闲超时调整。
两个变体方法
它们与上面的能力同族,按需要选用:
client.events.subscribeEventsBatch:一次订阅多类事件,等价于多次subscribeEvents,用于减少跨 FFI 的调用次数。client.sync.backfillConversationHistory:只回填单个会话的历史, 用于「进入某个老会话时才补」;bootstrapStartupHome的backfillVisibleHistories是它的批量版。
相关
- Client SDK 使用指南:完整接入顺序
- 可观察视图:打开会话与消息列表
- Client API 全表:逐方法签名