文档中心
IM 即时通讯
文档中心
体验 App
SDK 中心
API 中心
常见问题
代码市场
进入控制台
立即注册
登录
中文站 English
  • 文档中心
  • 即时通讯
  • 用户相关
  • 多端登录

多端登录

更新时间:2024-02-27 15:36

功能简介

ZIM SDK 支持配置自定义多端登录,即用户同一个账号可在多个平台上同时登录,满足用户的会话、消息、群组等数据互通。

  • 如需使用此功能,请开通专业版或旗舰版套餐,并联系技术支持开通服务并配置登录策略。
  • 本功能仅支持 2.11.0 及以上版本的 SDK 使用。

常见的登录策略

多端登录可支持在 Windows、Mac、Linux、Android、iOS、iPad、Web、小程序等八个平台上配置,其中支持在 Windows、Mac、Linux、Android、iOS、iPad 平台配置多设备登录,对于上述任一平台而言,一个账号在同一时间只能在最多两台设备上进行登录。在 Web 平台配置多实例登录,最多不超过 5 个登录实例。

以下为 ZIM SDK 支持的三种登录策略,即单平台登录、双平台登录以及多平台登录:

登录策略 具体说明
单平台登录(默认)
仅支持用户同时在 1 个平台上登录帐号。如果在其他平台上登录帐号,原平台上的账号会被退出。
双平台登录
支持用户在 Windows、Mac、Linux、Android、iOS 和 iPad 的其中 1 个平台上登录帐号,并同时保持帐号在 Web 平台在线。
多平台登录
是指支持用户同时在 Windows、Mac、Linux、Android、iOS、iPad、Web、小程序多平台登录帐号,支持以下配置:
  • 同一平台同时多设备、实例登录。
  • 配置互踢逻辑,当前仅支持 android、iOS 设备互踢,Windows、Mac 设备互踢。

前提条件

在实现“多端登录”功能之前,请确保:

  • 已在 ZEGO 控制台 创建项目,获取到了接入 ZIM SDK 服务所需的 AppID、AppSign。ZIM 服务权限不是默认开启的,使用前,请先在 ZEGO 控制台 自助开通 ZIM 服务(详情请参考控制台的 服务配置 - 即时通讯 - 开通服务),若无法开通 ZIM 服务,请联系 ZEGO 技术支持开通。
  • 已集成 ZIM SDK,详情请参考 快速开始 - 实现基本收发消息 的 “2 集成 SDK”。

实现流程

联系 ZEGO 技术支持,开通多端登录服务,配置多端登录之后,即可在多端调用 login 登录 ZIM SDK,实现流程与单端登录无异。如何登录,详情请参考 实现基本消息收发 的“登录 ZIM“。

当登录设备已达到策略规定的上限时,如果在新设备登录帐号,原设备中最早登录的帐号会被踢下线,并通过 onConnectionStateChanged 回调得知 event 为 KickedOut 。例如:登录策略规定最多只能在 3 台设备上登录,已在设备 A、B、C(按登录时间排序)登录,如果在设备 D 上登录帐号,则设备 A 上的帐号会被踢下线。

当帐号被踢下线后,建议调用 logout 接口登出 ZIM 服务,用户界面切换为登录界面。

多端登录对其他功能的影响

配置多端登录后,以下功能的代码也需要做相应调整。

用户信息管理

ZIM SDK 为多端登录用户提供了用户信息同步的功能。当用户在一端通过 updateUserName、updateUserAvatarUrl、updateUserExtendedData 接口更新了自己的信息后,其他在线客户端可通过 onUserInfoUpdated 事件监听用户信息被修改。

onUserInfoUpdated 处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onUserInfoUpdated(zim::ZIM * zim, const zim::ZIMUserFullInfo & info) override {
        // 可以在 info 中获取:用户 ID,用户名,用户头像,用户额外字段
        auto user_id = info.baseInfo.userID;
        auto user_name = info.baseInfo.userName;
        auto user_avatar_url = info.userAvatarUrl;
        auto user_extended_data = info.extendedData;
    }

...
}

会话管理

删除单个服务端会话

当用户在一端通过 deleteConversation 接口删除服务端会话后(即 isAlsoDeleteServerConversation 为 true),其他客户端可通过 onConversationChanged 事件监听会话被删除。

onConversationChanged 处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onConversationChanged(zim::ZIM *zim, 
                                       const std::vector<zim::ZIMConversationChangeInfo> &conversationChangeInfoList) override {
        for (const auto &conv_info : conversationChangeInfoList) {
            if (conv_info.event == zim::ZIMConversationEvent::ZIM_CONVERSATION_EVENT_DELETED) {
                // 会话被删除
            }
        }
    }

...
}

删除全部服务端会话

当用户在一端通过 deleteAllConversations 接口删除全部服务端会话后(即 isAlsoDeleteServerConversation 为 true),其他客户端可通过 onConversationsAllDeleted 事件监听全部会话被删除。

onConversationsAllDeleted 处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onConversationsAllDeleted(zim::ZIM *zim, 
                                       const ZIMConversationsAllDeletedInfo &info) override {
        //其他端删除了全部会话
   }
...
}

清楚全部会话未读

当用户在一端通过 clearConversationTotalUnreadMessageCount 清除全部会话未读时,其他客户端可通过 onConversationTotalUnreadMessageCountUpdated 事件监听所有会话的未读都被清零的通知。

onConversationTotalUnreadMessageCountUpdated 处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onConversationTotalUnreadMessageCountUpdated(zim::ZIM *zim, 
                                       unsigned int totalUnreadMessageCount) override {
        //其他端清除全部会话未读后,本端该通知totalUnreadMessageCount的值将为0
   }
...
}

消息管理

消息同步

当用户登录新设备后,SDK 不会自动将旧设备中的已有消息同步到新设备上,用户需要主动调用 queryHistoryMessage 接口,才能获取存储于 ZIM 服务端的消息,详情请参考 获取历史消息。对于存储于旧设备的本地消息,则无法获取。

删除服务端消息

当用户在一端通过 deleteMessages、deleteAllMessage、deleteAllConversationMessages 接口删除会话的服务端消息后(即 isAlsoDeleteServerMessage 为 true),其他客户端可通过 onMessageDeleted 事件监听消息被删除。

事件通知处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onMessageDeleted(zim::ZIM * /*zim*/, const zim::ZIMMessageDeletedInfo &deletedInfo) override {
        if (deletedInfo.messageDeleteType == zim::ZIM_MESSAGE_DELETE_TYPE_MESSAGE_LIST_DELETED)
        {
            // 某个会话中的多条消息被删除
            for (const auto& message : deletedInfo.messageList)
            {
                // 遍历每一条被删除的消息
            }
        } else if (deletedInfo.messageDeleteType ==
                   zim::ZIM_MESSAGE_DELETE_TYPE_CONVERSATION_ALL_MESSAGES_DELETED)
        {
            // 某个会话当前所有消息被删除
        } else if (deletedInfo.messageDeleteType ==
                   zim::ZIM_MESSAGE_DELETE_TYPE_ALL_CONVERSATION_MESSAGES_DELETED)
        {
            // 所有会话的所有消息被删除
        }
...
}

设置消息回执已读

当用户在一端通过 sendMessageReceiptsRead、sendConversationMessageReceiptRead 接口设置消息回执已读后,其他客户端可通过 onMessageReceiptChanged、onConversationMessageReceiptChanged 事件监听本帐号已设置消息回执为已读。

事件通知处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onMessageReceiptChanged(zim::ZIM * /*zim*/,
                const std::vector<zim::ZIMMessageReceiptInfo> & infos) override {
        for (const auto &info : infos) {
            if (info.isSelfOperated) {
                // 用户自己设置的消息回执已读
            }
        }
    }

    virtual void onConversationMessageReceiptChanged(zim::ZIM *zim, 
                const std::vector<zim::ZIMMessageReceiptInfo> &infos) override {
        for (const auto &info : infos) {
            if (info.isSelfOperated) {
                // 用户自己设置的消息回执已读
            }
        }
    }

...
}

房间管理

房间模块相关接口和事件不支持多端登录。用户在 A 设备加入房间后,然后在 B 设备再加入相同的房间后,会把 A 设备踢出房间,A 设备会通过 onRoomStateChanged 事件通知收到 event 为 ZIM_ROOM_EVENT_KICKED_OUT_BY_OTHER_DEVICE。

事件通知处理示例

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onRoomStateChanged(zim::ZIM *zim, zim::ZIMRoomState state, zim::ZIMRoomEvent event,
                                    const std::string &extendedData,
                                    const std::string &roomID) override {
        if (state == zim::ZIMRoomState::ZIM_ROOM_STATE_DISCONNECTED &&
            event == zim::ZIMRoomEvent::ZIM_ROOM_EVENT_KICKED_OUT_BY_OTHER_DEVICE) {
            // 多端登录加入房间,被踢出房间
        }
    }
...
}

群组管理

在开通多端登录服务后,ZIM SDK 会自动在多端设备之间同步群组相关数据。

呼叫邀请管理

当用户同时登录设备 A 和 B,用户收到呼叫邀请,在设备 A 上接受邀请(调用 callAccept)或者拒绝邀请(调用 callReject) 后:

  1. 设备 A 可以通过相关操作的回调(ZIMCallAcceptanceSentCallback 或 ZIMCallRejectionSentCallback) 得知操作结果,关闭邀请弹窗,实现其他业务操作;
  2. 设备 B 应当通过 onCallUserStateChanged 回调,得知本用户的呼叫用户状态(ZIMCallUserState)是 ZIM_CALL_USER_STATE_ACCEPTED 还是 ZIM_CALL_USER_STATE_REJECTED,关闭邀请弹窗,实现其他业务操作

各个设备能收到该呼叫内的用户状态变更事件 onCallUserStateChanged 如下表所示:

callUserState 设备 A 设备 B
Inviting ✔️ ✔️
Received ✔️ ✔️
Accepted ✔️ ✔️
Rejected ✔️ ✔️
Timeout ✖ ✖
Cancelled ✖ ✖
Quit ✔️ ✖

调用接口以及事件通知处理示例

const std::string self_user_id = "user_id";
const std::string current_call_id = "call_id";

zim::ZIMCallAcceptConfig accept_config;
accept_config.extendedData = "extra_1";

zim::ZIMCallRejectConfig reject_config;
reject_config.extendedData = "extra_1";

// 设备 A 接受邀请
zim_->callAccept(current_call_id, accept_config, [=] (const std::string &callID, const ZIMError &errorInfo) {
    // 关闭呼叫等待操作的弹框。
});
// 设备 A 拒绝邀请
zim_->callReject(current_call_id, reject_config, [=] (const std::string &callID, const ZIMError &errorInfo) {
    // 关闭呼叫等待操作的弹框。
});

// 设备 B 监听 onCallUserStateChanged

class zim_event_handler : public zim::ZIMEventHandler {
...

    virtual void onCallUserStateChanged(zim::ZIM * /*zim*/,
                                               const zim::ZIMCallUserStateChangeInfo &info,
                                               const std::string &callID) override {
        for (const auto &user_info : callUserList) {
            if (user_info.userID == self_user_id &&
                (user_info.state == zim::ZIMCallUserState::ZIM_CALL_USER_STATE_ACCEPTED ||
                 user_info.state == zim::ZIMCallUserState::ZIM_CALL_USER_STATE_REJECTED)) {
                // 其他设备已经接受或者拒绝呼叫,关闭呼叫等待操作的弹框
            }
        }
    }

...
}
本篇目录
  • 免费试用
  • 提交工单
    咨询集成、功能及报价等问题
    电话咨询
    400 1006 604
    咨询客服
    微信扫码,24h在线

    联系我们

  • 文档反馈