如何理解即时通讯业务中的实时消息、本地通知和 APNs 远程推送?

客户端弹出通知栏通知时并不一定都是远程推送。本文描述了 IM 连接状态、应用程序存活状态、本地通知、远程推送之间的关系。

SDK 与融云服务器的 IM 连接状态

为了区分实时消息和远程推送,我们需要先理解 IM 连接的几种状态:

  • 连接成功:应用程序调用 SDK 的连接方法后,SDK 与融云服务器建立一个长连接,用于消息的发送与接收,称之为 IM 连接通道。SDK 通过通过 IM 连接通道接收消息后会触发消息监听中的方法。

  • 无连接:如果 IM 连接通道 断开,则即时通讯实时消息无法通过 IM 长连接到达用户设备。此时如有新消息,应用程序仅能依赖 Apple 的推送服务(APNs)通知用户设备。

    以下情况会导致 IM 连接通道断开:

    • 应用程序的主进程被杀死或者回收。
    • 应用程序主动调用 SDK 的方法(disconnect)断开 IM 连接。
    • 未调用连接方法,或未正常建立 IM 连接。
    • 当前登录用户被封禁。
    • 当前用户的 Token 过期或被作废
    • 当前用户在其他设备登录,导致在当前设备上被踢下线(具体受当前 App Key 的多设备登录限制影响)

应用程序的状态

为了理解实时消息、本地通知和远程推送的作用范围,我们需要先区分 iOS 应用程序的几种状态,分别是前台状态,后台活动状态和后台暂停状态。

  1. 前台状态:应用程序在前台运行(假设 SDK 已经与融云服务器正常建立 IM 连接),用户此时正在使用应用程序。

  2. 后台活跃状态:应用程序进入到后台后最多活跃 2 分钟,此时 IM 连接仍然存在,应用程序可以通过 IM 连接通过接收实时消息。如果应用程序集成了 IMKit SDK,收到新消息后 IMKit 会负责在通知栏弹出通知,这种通知称为“本地通知”。如果应用程序集成了 IMLib SDK,收到新消息后会触发 IMLib 的消息监听方法(注意,IMLib 未实现该场景下的本地通知能力)。

  3. 后台暂停状态:应用程序在后台超过 2 分钟后进入到暂停状态,SDK 会在此时主动断开 IM 连接,此时应用程序失去了与融云服务器的 IM 连接。在 IM 连接通道 断开的情况下,如果有人给该用户发消息,必须依赖 Apple 的 APNs 远程推送服务通知用户设备。APNs 的推送通知可直接通过 iOS 系统在通知栏显示,不依赖 IMLib/IMKit 的实现。

在后两种状态下,如果程序重新回到前台并建立 IM 连接,SDK 可从融云服务端收取消息。

即时通讯实时消息

无论应用程序在前台或者后台,如果是由 IM 连接通知接收的消息,SDK 一定会触发消息监听的回调方法。

以 IMKit 的消息监听方法为例:

/**
 接收消息的回调方法

 @param message 当前接收到的消息
 @param nLeft 还剩余的未接收的消息数,left>=0
 @param offline 是否是离线消息
 @param hasPackage SDK 拉取服务器的消息以包(package)的形式批量拉取,有 package 存在就意味着远端服务器还有消息尚未被 SDK
 拉取
 */
- (void)onRCIMReceived:(RCMessage *)message
                  left:(int)nLeft
               offline:(BOOL)offline
            hasPackage:(BOOL)hasPackage;

本地通知

本地通知指应用在前台或后台活跃运行时,由 IMKit 或应用客户端直接调用系统接口创建并发送的通知。IMKit SDK 内部已经实现了本地通知功能,当应用处于后台接收到新消息时,IMKit 默认会在通知面板弹出通知提醒,即本地通知。

参考 IMKit 5. X 开发者文档:本地通知

远程推送

应用程序集成 APNs 服务后,在 IM 连接通道断开的情况下,可由 Apple 的 APNs 服务下发的收到新消息的通知。

参考开发者文档: 集成 APNs 远程推送