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

房间管理

更新时间:2024-11-05 11:30

功能简介

ZIM SDK 提供多人房间聊天功能,支持用户向房间内发送文本消息或自定义消息,实现了多人在线交流、同步分享。

多人房间聊天功能可应用于小班课或者会议室等场景,房间成员数量上限请参考 计费说明。

前提条件

在实现“房间管理”功能之前,请确保:

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

实现流程

用户可以通过以下两种方式,创建房间并进入房间。

  • 方式一:创建房间、加入房间:用户 A 调用 createRoom 接口,传入 ZIMRoomInfo 信息,即可创建并加入房间。其他用户调用 joinRoom 接口,传入由 A 创建的房间 roomID,即可加入房间。
  • 方式二:进入房间:用户 X 调用 enterRoom 接口,传入 ZIMRoomInfo 信息,如果 roomID 不存在,会自动创建一个房间然后进入。其他用户需要调用 enterRoom 接口,传入由 X 创建的房间 roomID,进入房间。

房间内的用户,可以通过 sendRoomMessage 接口,向房间内发送消息,详情请参考 收发房间消息。

如果 roomID 已存在:

  • 调用 createRoom 接口,会返回相关错误码,详情请参考 常见错误码。
  • 调用 enterRoom 接口,会直接进入此房间内。

如果 roomID 不存在:

  • 调用 createRoom 接口,可以直接创建、并加入到此房间内。
  • 调用 enterRoom 接口,会直接创建一个房间、并进入到此房间内。

创建房间、加入房间

以下流程中,我们以客户端 A 创建并加入房间,客户端 B 加入房间为例。

1. 注册回调

所有进入房间的用户,都需注册 onRoomMemberJoined、onRoomMemberLeft 和 onRoomStateChanged 回调,用于监听房间其他成员的变动和接收房间连接状态发生改变的事件通知。

注册 onRoomMemberJoined 回调示例源码:

void onRoomMemberJoined(ZIM * /*zim*/, const std::vector<ZIMUserInfo> & /*memberList*/,
    const std::string & /*roomID*/) override{

    }

注册 onRoomMemberLeft 回调示例源码:

void onRoomMemberLeft(ZIM * /*zim*/, const std::vector<ZIMUserInfo> & /*memberList*/,
    const std::string & /*roomID*/) override{

    }

注册 onRoomStateChanged 回调示例源码:

void onRoomStateChanged(ZIM * /*zim*/, ZIMRoomState /*state*/, ZIMRoomEvent /*event*/,
    const std::string & /*extendedData*/,
    const std::string & /*roomID*/)override{

    }

2. 创建房间

客户端 A 登录后,创建一个房间,可以调用 createRoom 接口,传入 ZIMRoomInfo 信息,即可创建并加入房间。同时可以通过错误信息 error_info 中的错误码 ZIMErrorCode 类型的参数值,判断是否创建成功。相关错误码请查看 常见错误码。

创建成功后会收到 onRoomStateChanged 的通知回调,ZIMRoomState 为 ZIM_ROOM_STATE_CONNECTED, ZIMRoomEvent 为 ZIM_ROOM_EVENT_SUCCESS。

  • “roomID”、“roomName” 支持开发者自定义规则生成。建议开发者将 “roomID” 设置为一个有意义的值,可将其与自己的业务账号系统进行关联。
  • 调用 createRoom 接口创建房间后,会直接加入房间,无需再调用 joinRoom 接口加入房间。
// roomID 最大 32 字节的字符串。仅支持数字,英文字符 和 '!', '#', '$', '%', '&', '(', ')', '+', '-', ':', ';', '<', '=', '.', '>', '?', '@', '[', ']', '^', '_', '{', '}', '|', '~'。
// roomName 最大 64 字节的字符串,无特殊字符限制。
ZIMRoomInfo room_info;
room_info.roomID = room_id;
room_info.roomName = room_name;

zim_->createRoom(room_info, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
    global_main_dialog_->PostUiThread([=] {});
    if (error_info.code != 0)
    {
        ShowMsg(L"创建房间失败,房间ID: %s, 错误码: %d", room_info.baseInfo.roomID, error_info.code);
    }
    else
    {
        ShowMsg(L"创建房间成功,房间ID: %s", room_info.baseInfo.roomID);
    }
});

3. 加入房间

客户端 B 加入房间,可以调用 joinRoom 接口,传入由 A 创建的房间 roomID,即可加入房间。同时可以根据错误码 ZIMErrorCode 的参数值,判断用户是否加入成功。相关错误码请查看 常见错误码。

加入成功后会收到 onRoomStateChanged 的通知回调,ZIMRoomState 为 ZIM_ROOM_STATE_CONNECTED, ZIMRoomEvent 为 ZIM_ROOM_EVENT_SUCCESS。

zim_->joinRoom(roomId, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
    global_main_dialog_->PostUiThread([=] {});
    if (error_info.code != 0)
    {
        ShowMsg(L"加入房间失败,房间ID: %s, 错误码: %d", room_info.baseInfo.roomID, error_info.code);
    }
    else
    {
        ShowMsg(L"加入房间成功,房间ID: %s, 房间名称: %s", room_info.baseInfo.roomID, room_info.baseInfo.roomName);
    }
});

4. 房间成员变动通知

当房间有其他成员加入时,将通过 setEventHandler 的回调接口 onRoomMemberJoined,向其他已在成员发送消息通知。

例如,当客户端 B 加入由 A 创建的房间时,A 将收到房间内成员变动的通知。

void onRoomMemberJoined(ZIM* zim, const std::vector<ZIMUserInfo>& member_list, const std::string& room_id)
{
    for (auto member : member_list)
    {
        ShowMsg(L"用户: (%s%s), 进入房间: %s", member.userID, member.userName, room_id);
    }
}

进入房间

以下流程中,我们以客户端 X 创建并进入房间,客户端 Y 直接进入房间为例。

  1. 注册 onRoomMemberJoined、onRoomMemberLeft 和 onRoomStateChanged 回调,详情请参考 创建房间、加入房间 - 1. 注册回调。
  2. 客户端 X 登录后,调用 enterRoom 接口,传入 ZIMRoomInfo 信息,进入房间;如果传入的 roomID 不存在,将会自动创建一个房间并进入该房间。
  3. 客户端 Y 登录后,调用 enterRoom 接口,传入由 X 创建的房间 roomID,直接进入房间。
  4. 加入房间成功后会收到 onRoomStateChanged 的通知回调,ZIMRoomState 为 ZIM_ROOM_STATE_CONNECTED, ZIMRoomEvent 为 ZIM_ROOM_EVENT_SUCCESS。
  5. 房间内的用户,同样可以使用 setEventHandler 的回调接口 onRoomMemberJoined 方法,实现对房间内成员加入的监听。
ZIMRoomInfo room_info;
room_info.roomID = room_id;
room_info.roomName = room_name;

ZIMRoomAdvancedConfig config;

zim_->enterRoom(room_info, config, [=](ZIMRoomFullInfo room_info, zim::ZIMError error_info) {
    global_main_dialog_->PostUiThread([=] {});
    if (error_info.code != 0)
    {
        ShowMsg(L"进入房间失败,房间ID: %s, 错误码: %d", room_info.baseInfo.roomID, error_info.code);
    }
    else
    {
        ShowMsg(L"进入房间成功,房间ID: %s", room_info.baseInfo.roomID);
    }
});

切换房间

如果用户想要从一个房间切换至另一个房间,可以调用 switchRoom 接口,传入原房间的 ID(fromRoomID)以及目标房间信息(toRoomInfo,含房间 ID 和房间名称),即可切换房间。

然而,可能因目标房间不存在而导致房间切换失败。如需避免这种失败,也可以在调用 switchRoom 接口时,传入 isCreateWhenRoomNotExisted 为 true(允许 ZIM 在房间不存在时创建新房间)和 config(用于配置新房间)。如此,当 ZIM 判断目标房间不存在时,就会根据 toRoomInfo 和 config(如有)创建新房间用于切换。

房间切换成功后,原房间内的其他用户可通过 setEventHandler 的回调接口 onRoomMemberLeft,得知有用户离开房间;目标房间内的其他用户可通过 setEventHandler 的回调接口 onRoomMemberJoined,得知有用户进入了房间。

  • 完整流程请参考下图:

  • 示例代码:

    std::string fromRoomID = "fromRoomID";
    auto toRoomInfo = zim::ZIMRoomInfo("toRoomID", "toRoomName");
    
    // 如果房间不存在时,是否创建房间。
    // 只有此为 true 且切换到的房间不存在时,toRoomInfo 中的 toRoomName 以及 config 才有意义
    bool isCreateWhenRoomNotExisted = true; 
    
    // 进阶配置,用于创建房间
    auto config = zim::ZIMRoomAdvancedConfig();
    config.roomAttributes.emplace("key1", "value1");
    config.roomDestroyDelayTime = 90;
    
    // 切换房间
    zim->switchRoom(
        fromRoomID, toRoomInfo, isCreateWhenRoomNotExisted, config,
        [=](const zim::ZIMRoomFullInfo &roomInfo, const zim::ZIMError &errorInfo) {
            if (errorInfo.code == zim::ZIMErrorCode::ZIM_ERROR_CODE_SUCCESS) {
                // 切换房间成功,开发者可以从 roomInfo 中获取切换后房间的信息
            }
        });

离开房间

用户如果想要离开房间,可以调用 leaveRoom 接口,传入房间的 roomID,即可退出此房间;房间内的其他用户可以通过 setEventHandler 的回调接口 onRoomMemberLeft,收到成员变动通知。

离开房间成功后会收到 onRoomStateChanged 的通知回调,ZIMRoomState 为 ZIM_ROOM_STATE_DISCONNECTED,ZIMRoomEvent 为 ZIM_ROOM_EVENT_SUCCESS。

离开房间后,将不能收到房间内的消息。

// 离开房间
zim->leaveRoom(room_id, [=](const std::string &roomID, const ZIMError &errorInfo) {

});
// 收到成员变动通知
void onRoomMemberLeft(ZIM* zim, const std::vector<ZIMUserInfo>& member_list, const std::string& room_id)
{
    for (auto member : member_list)
    {
        ShowMsg(L"用户: (%s,%s), 退出房间: %s", member.userID, member.userName, room_id);
    }
}

当所有成员离开房间后,房间将自动销毁。ZIM SDK 支持通过 ZIMRoomAdvancedConfig 设置房间延迟销毁,最大延迟为 3 小时。

退出所有房间

调用 leaveAllRoom 接口,即可立即离开当前加入的所有房间,并返回离开的房间列表。如果用户多端登录,则用户在一端调用此接口后,仅会退出在该端上加入的房间,在其他端加入的房间不受影响。

zim->leaveAllRoom([](const std::vector<std::string>& roomIDList, const ZIMError& errorInfo) {
    if (errorInfo.errorCode == 0) {
        //roomIDList 为离开的房间列表
    } else {
        //根据官网错误码表处理
    }
});

房间内的其他用户可以通过 setEventHandler 的回调接口 onRoomMemberLeft,收到成员变动通知。

退出所有房间成功后,用户会根据所离开房间的数量,多次收到 onRoomStateChanged 的通知回调,ZIMRoomState 为 ZIM_ROOM_STATE_DISCONNECTED, ZIMRoomEvent 为 ZIM_ROOM_EVENT_SUCCESS。

离开房间后,将不能收到房间内的消息。

销毁房间

开发者可以在后台调用 ZIM 服务端接口进行 销毁房间。房间被销毁后,用户通过 onRoomStateChanged 收到房间状态(ZIMRoomState)从 ZIM_ROOM_STATE_CONNECTED 转变为 ZIM_ROOM_STATE_DISCONNECTED 的事件通知。根据 ZIM SDK 版本不同,回调中描述导致房间连接状态发生变更的事件(ZIMRoomEvent)如下所示:

  • 当 ZIM SDK 版本小于 2.13.0 时,事件为 ZIM_ROOM_EVENT_KICKED_OUT。
  • 当 ZIM SDK 版本为 2.13.0 及之后版本时,事件为 ZIM_ROOM_EVENT_ROOM_NOT_EXIST。

网络中断对房间生命周期的影响

ZIM 房间类似于在线聊天室、网络中断会导致房间进入重连状态并抛出 onRoomStateChanged。详情请参考 场景 4 :ZIM 房间断网。

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

    联系我们

  • 文档反馈