开发者 · IM SDK

读取发布通道…

把即时通讯,装进你的 App。

Circllo IM SDK 是即时通讯平台的官方客户端 SDK,只提供数据与事件,不带 UI,界面完全由你自己决定。 iOS 与 Android 是同一套业务契约的两个实现,行为一致、同号发版。

下载

下载地址由各端清单文件(android.json / ios.json)动态生成,文件名带版本与构建号,历史版本不会被就地覆盖。

接入步骤

先分清三个角色:你的 App(集成 SDK)、你的后端(签发 UserSig)、Circllo IM 平台(收发消息)。

开工前必读的两条
  • AppSecret 绝不进 App。它只存在于你的后端,用来签 UserSig。一旦打进客户端包,任何人都能解出来冒充你的用户。
  • UserSig / expireAt / nonce 三个值必须来自同一次签发,原样透传。后两个是被签进签名串的输入,App 端改一个字节或自造 nonce,验签必失败。
  • 网关地址不由你配置。REST 与 WSS 地址由 SDK 内置的环境枚举决定,接入方传不进也覆盖不了。当前 TESTPROD 解析到同一套测试网关,PROD 不代表生产 IM 已开通。
1引入 AAR

把下载的 .aar 放进模块的 libs/,然后声明依赖。SDK 自带 consumer-rules.pro,接入方无需再写 keep 规则。

dependencies {
    implementation(files("libs/impaas-sdk-release.aar"))

    // AAR 不传递依赖,这几个要自己声明
    implementation("com.squareup.okhttp3:okhttp:4.12.0")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
    implementation("androidx.security:security-crypto:1.1.0-alpha06")
    implementation("com.google.crypto.tink:tink-android:1.8.0")
}
2声明权限

SDK 的 library manifest 已经声明并会自动合并进宿主 App,通常无需重复添加;下面两条列出来只是让你知道 SDK 用到什么。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
3初始化

建议放在 Application.onCreate网关地址由 SDK 内置,接入方只需要给 appId 和环境枚举,不需要也不能传 host。

import wang.into.im.impaas.core.IMPaaSEnvironment

IMPaaSClient.init(
    context = applicationContext,
    config = IMPaaSConfig(
        appId = "APP_ID",                      // 开通时分配,公开
        environment = IMPaaSEnvironment.TEST,  // TEST / PROD,网关地址由 SDK 内置
    ),
)
4注册监听

回调都在主线程,可直接刷 UI。未知事件会降级透出,不抛异常也不丢消息。

IMPaaSClient.addListener(object : IMPaaSListener {
    override fun onConnected() { /* 长连就绪 */ }
    override fun onNewMessage(message: IMPaaSMessage) { /* 按 messageId 去重后刷 UI */ }
    override fun onMessageEvent(event: IMEvent) { /* message.* 其余事件 */ }
    override fun onUnknownEvent(event: IMEvent) { /* 表外事件,降级不抛不丢 */ }
    override fun onKicked(reason: KickReason) { /* 顶号/封禁,引导重登 */ }
})

// refresh_token 也失效时:重新向你的后端取 UserSig 再 login
IMPaaSClient.onNeedReLogin = { /* ... */ }
5登录

三个值先从你的后端取(那里才有 AppSecret),拿到后原样透传。成功后 SDK 自动建立长连。

IMPaaSClient.login(
    userId   = "player_888",
    userSig  = sig.userSig,
    expireAt = sig.expireAt,   // 绝对 Unix 秒,必须 > 0
    nonce    = sig.nonce,      // 8~64 字符,不可复用
) { result ->
    result.onSuccess { /* SDK 已自动建立 WSS */ }
          .onFailure { e -> /* e is IMPaaSError */ }
}
6收发消息
val msg = IMPaaSMessage.text("hello", conversationId = "conv_id")
IMPaaSClient.message.send(msg) { result ->
    result.onSuccess { sent -> /* messageId / seqId / createdAt 已回填 */ }
          .onFailure { e -> /* 失败 */ }
}

几条容易踩的

  • id 一律当不透明字符串:不解析、不转整数、不做数值比较。排序用 seq_id(会话内序号)或 created_at
  • 发消息没有「单聊/群聊」参数:单聊还是群聊由会话本身决定,send 只认 conversation_id。群 id 就是 conversation_id,没有单独的 group_id。
  • 收到不认识的消息体裁或事件不要当异常:平台下发的类型多于 SDK 当前识别的,SDK 会降级透出。按未知处理即可,不要中断流程。
  • token 与租户绑定:不要跨 appId 复用 token。token 过期 SDK 自动刷新,只有 refresh 也失效才回调 onNeedReLogin

需要更多

需要 appId、网关地址或完整的 API 参考(getting-started · android-integration · ios-integration · api-reference), 发信到 hello@circllo.app 联系我们。