聊天室

集成聊天室必读

聊天室功能概述

聊天室特点:

PC端聊天室SDK提供了不同于IMSDK的动态链接库(nim_chatroom.dll),因此加载使用聊天室功能有以下准备工作:

将SDK 相关的dll 文件(nim_chatroom.dll)放到App 的运行目录下。SDK 基于vs2010 开发,如果App 没有对应的运行时库文件(msvcp100.dll和msvcr100.dll),请将其放到App 的运行目录下。

准备工作完成后,在程序启动时,初始化SDK;在程序退出前,清理SDK。示例代码如下:

C++ 初始化参数: nim_chatroom::ChatRoomPlatformConfig 非必须参数,参考

void Init()
{
    nim_chatroom::ChatRoom::Init("");
}

void Cleanup()
{
    nim_chatroom::ChatRoom::Cleanup();
}

C#

void Init()
{
    NIMChatRoom.ChatRoomApi.Init();
}

void Cleanup()
{
    NIMChatRoom.ChatRoomApi.Cleanup();
}

C

typedef void(*nim_chatroom_init)(const char *json_extension);
typedef    void(*nim_chatroom_cleanup)(const char *json_extension);

void Init()
{
    //获取SDK初始化接口
    HINSTANCE hInst = LoadLibraryW(L"nim_chatroom.dll");
    nim_chatroom_init func = (nim_chatroom_init) GetProcAddress(hInst, "nim_chatroom_init");

    //初始化SDK
    func("");
}

void Cleanup()
{
    nim_chatroom_cleanup func = (nim_chatroom_cleanup) GetProcAddress(hInst, "nim_chatroom_cleanup");
    func("");
    FreeLibrary(hInst);
}

代理设置

chatroom SDK 支持 socks4、socks4a、socks5代理.

API原型

参数说明

参数 类型 说明
type NIMChatRoomProxyType 代理类型
host string 代理地址
port int 端口
user string 账号
password string 密码

返回值说明

无返回值。

进入聊天室

进入聊天室前,需要通过调用IM模块接口获取进入聊天室的权限,注意:这里调用的是IMSDK模块的接口

C++

void OnChatRoomRequestEnterCallback(int error_code, const std::string& result)
{
}

void foo()
{
    //获取聊天室登录信息
    nim::PluginIn::ChatRoomRequestEnterAsync(room_id, &OnChatRoomRequestEnterCallback);
}

C#

void foo()
{
    NIM.Plugin.ChatRoom.RequestLoginInfo(roomId, (response, authResult) =>
    {
        if (response == NIM.ResponseCode.kNIMResSuccess)
        {

        }
    });
}

C

typedef void(*nim_plugin_chatroom_request_enter_async)(const __int64 room_id, const char *json_extension, nim_plugin_chatroom_request_enter_cb_func cb, const void *user_data);

void CallbackRequestChatRoomEnter(int error_code, const char *result, const char *json_extension, const void *user_data)
{    
    //result为权限信息
}

void foo()
{
    HINSTANCE hInst = LoadLibraryW(L"nim.dll");
    nim_plugin_chatroom_request_enter_async func = (nim_plugin_chatroom_request_enter_async) GetProcAddress(hInst, "nim_plugin_chatroom_request_enter_async");

    func(room_id, null, &CallbackRequestChatRoomEnter, null);
}

获取权限成功后会得到权限信息(回调函数第二个参数result),接下去再调用进入聊天室的接口。

C++

void foo()
{
    ChatRoomEnterInfo info;
    ChatRoom::Enter(room_id_, room_enter_token, info);
}

C#

void foo()
{
    NIMChatRoom.LoginData data = new NIMChatRoom.LoginData();
    data.Nick = "【C# Client】";
    NIMChatRoom.ChatRoomApi.Login(roomId, authResult, data);
}

C typedef bool(nim_chatroom_enter)(const __int64 room_id, const char request_enter_data, const char enter_info, const char json_extension);

void foo()
{
    //获取进入聊天室接口
    HINSTANCE hInst = LoadLibraryW(L"nim_chatroom.dll");
    nim_chatroom_enter func = (nim_chatroom_enter) GetProcAddress(hInst, "nim_chatroom_enter");

    //聊天室可选参数
    Json::Value info_value;
    info_value[kNIMChatRoomEnterKeyNick] = "my_nickname_of_room";//设置聊天室内的昵称
    info_value[kNIMChatRoomEnterKeyAvatar] = "http://my_avatar_url";//设置聊天室内的头像地址
    info_value[kNIMChatRoomEnterKeyExt] = GetJsonStringWithNoStyled(JSON_OBJECT);//设置扩展字段
    info_value[kNIMChatRoomEnterKeyNotifyExt] = GetJsonStringWithNoStyled(JSON_OBJECT);//设置扩展字段用于通知

    //这里直接将权限信息作为参数传入
    func(room_id, result, GetJsonStringWithNoStyled(info_value).c_str(), "");
}

进入聊天室前需要提前注册一些全局回调(具体说明请参阅API 文档),以下以注册进入聊天室结果通知回调为例:

C++

void OnEnterCallback(__int64 room_id, const NIMChatRoomEnterStep step, int error_code, const ChatRoomInfo& info, const ChatRoomMemberInfo& my_info)
{
    if (step != kNIMChatRoomEnterStepRoomAuthOver)
        return;

        if (error_code != nim::kNIMResSuccess && error_code != nim::kNIMResTimeoutError)
        {
            std::wstring kick_tip_str;
            switch (error_code)
            {
            case nim::kNIMResNotExist:
                kick_tip_str = L"聊天室不存在";
                break;
            case nim::kNIMResForbidden:
                kick_tip_str = L"权限问题";
                break;
            case nim::kNIMResRoomLinkError:
            case nim::kNIMResRoomError:
                kick_tip_str = L"聊天室异常";
                break;
            case nim::kNIMResRoomBlackBeOut:
                kick_tip_str = L"黑名单用户禁止进入聊天室";
                break;
            case nim::kNIMResFrequently:
                kick_tip_str = L"操作太频繁,稍后重试";
                break;
            default:
                return;
            }
        }
        else
        {

        }
}

void foo()
{
    ChatRoom::RegEnterCb(&OnEnterCallback);
}

C#

void ChatRoomApi_LoginHandler(NIMChatRoom.NIMChatRoomLoginStep loginStep, NIM.ResponseCode errorCode, NIMChatRoom.ChatRoomInfo roomInfo, NIMChatRoom.MemberInfo memberInfo)
{
    if (loginStep == NIMChatRoom.NIMChatRoomLoginStep.kNIMChatRoomLoginStepRoomAuthOver && errorCode == NIM.ResponseCode.kNIMResSuccess)
    {
    }
    if (errorCode != NIM.ResponseCode.kNIMResSuccess)
    {
        MessageBox.Show(loginStep.ToString() + " " + errorCode.ToString(), "进入聊天室出错");
    }
}

void foo()
{
    NIMChatRoom.ChatRoomApi.LoginHandler += ChatRoomApi_LoginHandler;
}

C

typedef void(*nim_chatroom_reg_enter_cb)(const char *json_extension, nim_chatroom_enter_cb_func cb, const void *user_data);

static void CallbackEnter(__int64 room_id, int step, int error_code, const char *result, const char *json_extension, const void *user_data)
{

}

void foo()
{
    nim_chatroom_reg_enter_cb func = (nim_chatroom_reg_enter_cb)GetProcAddress(hInst, "nim_chatroom_reg_enter_cb");
    func(nullptr, &CallbackEnter, nullptr);    
}

离开聊天室(被踢)

调用接口nim_chatroom_exit 离开聊天室。

C++

void foo()
{
    ChatRoom::Exit(room_id);
}

C#

void foo()
{
    NIMChatRoom.ChatRoomApi.Exit(roomId);
}

C typedef void(nim_chatroom_exit)(const __int64 room_id, const char json_extension);

void foo()
{
    nim_chatroom_exit func = (nim_chatroom_exit) GetProcAddress(hInst, "nim_chatroom_exit");
    func(room_id, nullptr);
}

被踢出聊天室时,开发者可以通过接口nim_chatroom_reg_exit_cb注册全局通知回调函数获取离开聊天室的原因。

C++

void OnEnterCallback(__int64 room_id, int error_code, NIMChatRoomExitReason exit_reason)
{

}

void foo()
{
    ChatRoom::RegExitCb(&OnExitCallback);
}

C#

void ChatRoomApi_ExitHandler(long roomId, NIM.ResponseCode errorCode, NIMChatRoom.NIMChatRoomExitReason reason)
{
    if (errorCode == NIM.ResponseCode.kNIMResSuccess)
    {
    }
}

void foo()
{
    NIMChatRoom.ChatRoomApi.ExitHandler += ChatRoomApi_ExitHandler;
}

C

static void CallbackExit(__int64 room_id, int error_code, int exit_reason, const char *json_extension, const void *user_data)
{
    ...
}

typedef void(*nim_chatroom_reg_exit_cb)(const char *json_extension, nim_chatroom_exit_cb_func cb, const void *user_data);

void foo()
{
    nim_chatroom_reg_exit_cb func = (nim_chatroom_reg_exit_cb) GetProcAddress(hInst, "nim_chatroom_reg_exit_cb");
    func("", &CallbackExit, "");
}    

除了被多端、主播和管理员踢出以外,聊天室被关闭或者被解散也会收到离开聊天室的通知。

聊天室连接情况通知

通过接口nim_chatroom_reg_link_condition_cb 来当前连接情况变更回调函数,开发者可以通过回调函数获取当前连接情况。 C++

void OnRegLinkConditionCallback(__int64 room_id, const NIMChatRoomLinkCondition condition)
{

}

void foo()
{
    ChatRoom::RegLinkConditionCb(&OnRegLinkConditionCallback);
}

C++

void OnRegLinkConditionCallback(__int64 room_id, const NIMChatRoomLinkCondition condition)
{

}

void foo()
{
    ChatRoom::RegLinkConditionCb(&OnRegLinkConditionCallback);
}

C#

void ChatRoomApi_LinkStateChanged(long roomId, NIMChatRoomLinkCondition state)
{

}

void foo()
{
    NIMChatRoom.ChatRoomApi.LinkStateChanged += ChatRoomApi_LinkStateChanged;
}

C

static void CallbackLinkCondition(__int64 room_id, int condition, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_reg_link_condition_cb)(const char *json_extension, nim_chatroom_link_condition_cb_func cb, const void *user_data);

void foo()
{
    nim_chatroom_reg_link_condition_cb func = (nim_chatroom_reg_link_condition_cb) GetProcAddress(hInst, "nim_chatroom_reg_link_condition_cb");
    func(nullptr, &CallbackLinkCondition, nullptr);
}

获取/更新聊天室信息

进入聊天室的回调函数中会有聊天室的信息,此外还能通过单独的接口获取聊天室信息。SDK 本地不缓存聊天室信息,只提供向服务器查询的接口,因此接口调用遵循服务器接口使用频率限制。

C++

void OnGetChatRoomInfoCallback(__int64 room_id, int error_code, const ChatRoomInfo& info)
{
    if (error_code != nim::kNIMResSuccess || room_id != room_id_)
    {
        return;
    }
}

void foo()
{
    ChatRoom::GetInfoAsync(room_id, &OnGetChatRoomInfoCallback);
}

C#

void foo()
{
    NIMChatRoom.ChatRoomApi.GetRoomInfo(roomId, (room_Id, errorCode, info) =>
    {
    });
}

C

static void CallbackGetChatRoomInfo(__int64 room_id, int error_code, const char *result, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_get_info_async)(const __int64 room_id, const char *json_extension, nim_chatroom_get_info_cb_func cb, const void *user_data);

void foo()
{
    nim_chatroom_get_info_async func = (nim_chatroom_get_info_async) GetProcAddress(hInst, "nim_chatroom_get_info_async");
    func(room_id, nullptr, &CallbackGetChatRoomInfo, nullptr);
}

更新聊天室信息(需要管理员权限),目前只支持更新kNIMChatRoomInfoKeyName, kNIMChatRoomInfoKeyAnnouncement, kNIMChatRoomInfoKeyBroadcastUrl, kNIMChatRoomInfoKeyExt四个字段。

C++

void UpdateRoomCallback(int64_t room_id, int error_code)
{

}

void foo()
{
    ChatRoomInfo info;
    info.announcement_ = ; //聊天室公告
    info.name_ = ; //聊天室名称
    ChatRoom::UpdateRoomInfoAsync(room_id, info, true, "广播通知", &UpdateRoomCallback);
}

C#

NIMChatRoom.ChatRoomApi.UpdateRoomInfo(long roomId, ChatRoomInfo info, UpdateRoomInfoDelegate cb, bool notify, string notify_ext);

目前只支持更新ChatRoomInfo 的RoomName,Announcement,BroadcastUrl,Extension 四个属性。

C

void CallbackUpdateRoomInfo(int64_t room_id, int error_code, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_update_room_info_async)(const int64_t room_id, const char *room_info_json_str, bool need_notify, const char *notify_ext, const char *json_extension, nim_chatroom_update_room_info_cb_func cb, const void *user_data);

void foo()
{
    nim_chatroom_update_room_info_async func = (nim_chatroom_update_room_info_async) GetProcAddress(hInst, "nim_chatroom_update_room_info_async");

    Json::Value values;
    values[kNIMChatRoomInfoKeyName] = name_; //聊天室名称
    values[kNIMChatRoomInfoKeyAnnouncement] = announcement_; //聊天室公告
    values[kNIMChatRoomInfoKeyBroadcastUrl] = broadcast_url_; //视频直播拉流地址
    values[kNIMChatRoomInfoKeyExt] = ext_; //第三方扩展字段
    Json::FastWriter fw;

    func(room_id, fw.write(values).c_str(), true, "广播通知", nullptr, &CallbackUpdateRoomInfo, nullptr);
}

更新自己的信息

目前只支持更新kNIMChatRoomMemberInfoKeyNick, kNIMChatRoomMemberInfoKeyAvatar, kNIMChatRoomMemberInfoKeyExt三个字段, V3.8.0开始可以通过参数持久化固定成员的资料:

C++

void UpdateMyRoleCallback(int64_t room_id, int error_code)
{

}

void foo()
{
    ChatRoomMemberInfo info;
    info.nick_ = ; //聊天室内的昵称字段
    info.avatar_ = ; //聊天室内的头像
    info.ext_ = ;  //开发者扩展字段

    Json::Value values;
    values[nim_chatroom::kNIMChatRoomUpdateMyRoleExtNeedSave] = ; //bool 是否持久化
    Json::FastWriter fw;
    std::string extension = fw.write(values);

    ChatRoom::UpdateMyRoomRoleAsync(room_id, info, true, "广播通知", &UpdateMyRoleCallback, extension);
}

C#

ChatRoomApi.UpdateMyRoleInfo.UpdateMyRoleInfo(long roomId, MemberInfo info, UpdateMyRoleDelegate cb, bool notify, string notify_ext, string json_extension)

目前只支持更新 MemberInfo 的 Nick, MemberIcon,Extension 三个属性

C

void CallbackUpdateMyRoomRole(int64_t room_id, int error_code, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_update_my_role_async)(const int64_t room_id, const char *role_info_json_str, bool need_notify, const char *notify_ext, const char *json_extension, nim_chatroom_update_my_role_cb_func cb, const void *user_data);

void foo()
{
    nim_chatroom_update_my_role_async func = (nim_chatroom_update_my_role_async) GetProcAddress(hInst, "nim_chatroom_update_my_role_async");

    Json::Value values;
    values[kNIMChatRoomMemberInfoKeyNick] = id_; //聊天室内的昵称字段
    values[kNIMChatRoomMemberInfoKeyAvatar] = name_; //聊天室内的头像
    values[kNIMChatRoomMemberInfoKeyExt] = announcement_; //开发者扩展字段
    Json::FastWriter fw;


    Json::Value ext_values;
    ext_values[nim_chatroom::kNIMChatRoomUpdateMyRoleExtNeedSave] = ; //bool 是否持久化
    std::string extension = fw.write(values);

    func(room_id, fw.write(values).c_str(), true, "广播通知", extension.c_str(), &CallbackUpdateMyRoomRole, nullptr);
}

聊天室消息收发

聊天室SDK 支持文本、图片、音频、视频、地理位置、通知消息、提醒消息、文件消息和自定义消息等多种种类型消息。

查询消息历史

SDK 本地不缓存任何消息历史,只提供向服务器查询消息历史的接口,因此接口调用遵循服务器接口使用频率限制。

C++

void GetMsgHistoryCallback(__int64 room_id, int error_code, const std::list<ChatRoomMessage>& msgs)
{
    if (error_code != nim::kNIMResSuccess)
        return;
}

void foo()
{
    ChatRoomGetMsgHistoryParameters history_param;
    history_param.limit_ = 10;
    history_param.start_timetag_ = 0;
    ChatRoom::GetMessageHistoryOnlineAsync(room_id, history_param, &GetMsgHistoryCallback);
}

C#

void foo()
{
    NIMChatRoom.ChatRoomApi.QueryMessageHistoryOnline(roomId, 0, 50, (room_Id, errorCode, messages) =>
    {
        if (errorCode == NIM.ResponseCode.kNIMResSuccess)

    });
}

C

typedef void(*nim_chatroom_get_msg_history_online_async)(const __int64 room_id, const char *parameters_json_str, const char *json_extension, nim_chatroom_get_msg_cb_func cb, const void *user_data);

static void CallbackGetMsgHistoryOnline(__int64 room_id, int error_code, const char *result, const char *json_extension, const void *user_data)
{

}

void foo()
{
    nim_chatroom_get_msg_history_online_async func = (nim_chatroom_get_msg_history_online_async) GetProcAddress(hInst, "nim_chatroom_get_msg_history_online_async");

    Json::Value values;
    values[kNIMChatRoomGetMsgHistoryKeyStartTime] = start_timetag_;    //开始时间,单位毫秒
    values[kNIMChatRoomGetMsgHistoryKeyLimit] = limit_;                //本次返回的消息数量

    Json::FastWriter fw;

    func(room_id, fw.write(values).c_str(), nullptr, &CallbackGetMsgHistoryOnline, nullptr);
}

获取聊天室在线成员

SDK 本地不缓存聊天室成员信息,只提供向服务器查询的接口,因此接口调用遵循服务器接口使用频率限制。

SDK 提供了两种获取聊天室在线成员信息的接口:

踢出在线成员

C++

void KickMemberCallback(__int64 room_id, int error_code)
{
    if (error_code != nim::kNIMResSuccess)
        return;
}

void foo()
{
    ChatRoom::KickMemberAsync(room_id, user_account, "", &KickMemberCallback);
}

C#

void foo()
{
    NIMChatRoom.ChatRoomApi.RemoveMember(roomId, "userId", "踢出提示文本", (room_Id, errorCode) =>
    {
    });
}

C

typedef void(*nim_chatroom_kick_member_async)(const __int64 room_id, const char *id, const char *notify_ext, const char *json_extension, nim_chatroom_kick_member_cb_func cb, const void *user_data);

static void CallbackKickMember(__int64 room_id, int error_code, const char *json_extension, const void *user_data)
{

}

void foo()
{
    nim_chatroom_kick_member_async func = (nim_chatroom_kick_member_async) GetProcAddress(hInst, "nim_chatroom_kick_member_async");

    func(room_id, id, nullptr, nullptr, &CallbackKickMember, nullptr);
}

聊天室权限设置

设置管理员、设置普通成员、设置黑名单、禁言通过调用同一个接口nim_chatroom_set_member_attribute_async实现。

设置管理员

C++

    void SetMemberAttributeCallback(__int64 room_id, int error_code, const ChatRoomMemberInfo& info)
    {
        if (error_code != nim::kNIMResSuccess)
            return;
    }

    void foo()
    {
        ChatRoomSetMemberAttributeParameters param;
        param.account_id_ = user_account;
        param.attribute_ = kNIMChatRoomMemberAttributeMuteList;
        param.opt_ = true;

        ChatRoom::SetMemberAttributeOnlineAsync(room_id, param, &SetMemberAttributeCallback);
    }

C#

    void foo()
    {
        MemberProperty prop = new MemberProperty();
        prop.MemberId = "user_id";
        prop.Attribute = NIMChatRoomMemberAttribute.kNIMChatRoomMemberAttributeAdminister;
        NIMChatRoom.ChatRoomApi.SetMemberPropertyOnline(roomId, prop, (room_Id, errorCode, info) =>
        {
        });
    }

C

    typedef void(*nim_chatroom_set_member_attribute_async)(const __int64 room_id, const char *parameters_json_str, const char *json_extension, nim_chatroom_set_member_attribute_cb_func cb, const void *user_data);

    void foo()
    {
        nim_chatroom_set_member_attribute_async func = (nim_chatroom_set_member_attribute_async) GetProcAddress(hInst, "nim_chatroom_set_member_attribute_async");

        Json::Value values;
        values[kNIMChatRoomSetMemberAttributeKeyAccoutID] = account_id_;    //成员ID    
        values[kNIMChatRoomSetMemberAttributeKeyNotifyExt] = notify_ext_;    //通知的扩展字段

        //设置管理员枚举值
        values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeAdminister;    

        //设置管理员true,取消管理员false    
        values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;                                            

        Json::FastWriter fw;

        func(room_id, fw.write(values).c_str(), nullptr, &CallbackSetMemberAtribute, nullptr);
    }

设置普通成员

设置普通成员通过将上面代码片段中的“设置管理员枚举值”修改为设置普通成员枚举值即可

    values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeNomalSold;

    //设置普通成员true,取消普通成员false    
    values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;                

拉黑

设置普通成员通过将上面代码片段中的“设置管理员枚举值”修改为设置黑名单枚举值即可

        values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeBlackList;    

        //拉黑true,取消拉黑false
        values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;

禁言

设置普通成员通过将上面代码片段中的“设置管理员枚举值”修改为设置禁言枚举值即可

        values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeMuteList;    

        //禁言true,取消禁言false    
        values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;

临时禁言

可以设置时间长度,当时间到达设置的时长,自动解除禁言

C++

    void TempMuteCallback(__int64 room_id, int error_code, const ChatRoomMemberInfo& info)
    {
        if (error_code != nim::kNIMResSuccess)
            return;
    }

    void foo()
    {
        ChatRoom::TempMuteMemberAsync(room_id, user_account, 60, true, "", &TempMuteCallback);
    }

C#

    void foo()
    {
        ChatRoomApi.TempMuteMember(roomId, accid, 120,
        (roomId, errorCode, info) =>
        {
        }, true, accid + " 被禁言120s");
    }

C

    void CallbackTempMuteMember(int64_t room_id, int error_code, const char *result, const char *json_extension, const void *user_data)
    {
        // 解析result
    }

    typedef void(*nim_chatroom_temp_mute_member_async)(const int64_t room_id, const char *accid, const int64_t duration, bool need_notify, const char *notify_ext, const char *json_extension, nim_chatroom_temp_mute_member_cb_func cb, const void *user_data);

    void foo()
    {
        nim_chatroom_temp_mute_member_async func = (nim_chatroom_temp_mute_member_async) GetProcAddress(hInst, "nim_chatroom_temp_mute_member_async");

        func(room_id, "user_id", 60, true, "某人被禁言了", nullptr, &CallbackTempMuteMember, nullptr);
    }

聊天室队列服务