Windows/macOS

聊天室管理

更新时间: 2023/06/15 09:29:31

聊天室功能概述

聊天室特点:

  • 进入聊天室时必须建立新的连接,退出聊天室或者被踢会断开连接,在聊天室中掉线会有自动重连,开发者需要监听聊天室连接状态来做出正确的界面表现。
  • 支持聊天人数无上限。
  • 支持同时进入多个聊天室,会建立多个连接。
  • 支持多端进入同一个聊天室。
  • 支持自定义登录鉴权方式
  • 断开聊天室连接后,服务器不会再推送该聊天室的消息给此用户。
  • 聊天室成员分固定成员和游客两种类型。

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 非必须参数,参考

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

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

C#

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

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

C

ctypedef 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原型

  • C++

    void SetProxy(NIMChatRoomProxyType type, const std::string& host, int port, const std::string& user, const std::string& password)

    File:nim_chatroom\api\nim_chatroom_cpp.h

    Namespace:nim_chatroom

    Class:ChatRoom

  • C#

    void SetProxy(NIMChatRoomProxyType type,string host,int port,string user,string password)

    Namespace:NIMChatRoom

    Class:ChatRoomApi

  • C

    void nim_chatroom_set_proxy(enum NIMChatRoomProxyType type, const char *host, int port, const char *user, const char *password)

    File:nim_chatroom\api\nim_chatroom.h

参数说明

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

返回值说明

无返回值。

进入聊天室

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

C++

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

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

C#

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

C

ctypedef 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++

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

C#

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

C

ctypedef 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++

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#

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

ctypedef 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);	
}

聊天室多端登录

支持设置聊天室多端登录策略,即当同账号在不同客户端登录时,是否可以同时进入同一个聊天室。可以进入云信控制台选择应用 > IM专业版 > 功能配置 > 聊天室配置 > 聊天室多端登录配置进行设置。

  • 只允许一端登录,Windows、Web、Android、iOS 彼此互踢。同一账号仅允许在一台设备上登录。当该账号在另一台设备上成功登录时,新设备会将旧设备踢下线。
  • 各端均可以同时登录在线。最多可支持10个设备同时在线,在设备数上限内,所有的新设备再次登录,均不会将在线的旧设备踢下线。

控制台修改多端互踢的逻辑之后,下次新的设备登录时才会基于新的多端互踢策略进行校验,已经建立连接的设备不会因为策略的修改被强制踢出。

如果某台设备重复登录同一个聊天室,后登录的会将前面的长连接断开,此时会再触发一次进入聊天室的抄送,但是不会触发退出聊天室的抄送。关于进出聊天室(eventType=9)的抄送请参见聊天室事件抄送

离开聊天室(被踢)

调用接口nim_chatroom_exit 离开聊天室。

C++

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

C#

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

C

ctypedef 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++

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

}

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

C#

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

cstatic 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++

c++void OnRegLinkConditionCallback(__int64 room_id, const NIMChatRoomLinkCondition condition)
{

}

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

C++

c++void OnRegLinkConditionCallback(__int64 room_id, const NIMChatRoomLinkCondition condition)
{

}

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

C#

c#void ChatRoomApi_LinkStateChanged(long roomId, NIMChatRoomLinkCondition state)
{

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

C

cstatic 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++

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#

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

C

cstatic 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++

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#

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

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

C

cvoid 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++

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

cvoid 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 支持文本、图片、音频、视频、地理位置、通知消息、提醒消息、文件消息和自定义消息等多种种类型消息。

  • 为保证用户体验(如避免服务器过载),目前针对消息接收,有两套流控机制。第一套针对普通消息,聊天室用户每秒至多可接收20条,超过部分会因为流控随机丢弃。第二套针对高优先级消息,每秒至多接收10条,超过部分无法保证不丢失。
  • 为避免丢失重要消息(通常为服务端消息),可将发送聊天室消息的 HighPriority 参数设置为 true 实现高优先级接收服务端消息,进而保证高优先级消息流控上限内(每秒10条)的重要消息不丢失。详情请参见发送聊天室消息中的 HighPriority 参数说明。
  • 发送消息

1秒内默认最多可调该接口100次。如需上调上限,请在官网首页通过微信、在线消息或电话等方式咨询商务人员。

以发送文本消息的为例:.

C++

c++void foo()
{
std::string send_msg = ChatRoom::CreateRoomMessage(kNIMChatRoomMsgTypeText, QString::GetGUID(), text, ChatRoomMessageSetting());
ChatRoom::SendMsg(room_id_, send_msg);
}

C#

c#void foo()
{
	NIMChatRoom.Message msg = new NIMChatRoom.Message();
	msg.MessageType = NIMChatRoom.NIMChatRoomMsgType.kNIMChatRoomMsgTypeText;
	msg.MessageAttachment = "这是一条测试消息 " + DateTime.Now.ToString() + " " + new Random().NextDouble().ToString();
	NIMChatRoom.ChatRoomApi.SendMessage(roomId, msg);
}

C

ctypedef void(*nim_chatroom_send_msg)(const __int64 room_id, const char *msg, const char *json_extension);

void foo()
{
	Json::Value values;
	values[kNIMChatRoomMsgKeyFromNick] = from_nick;			//消息发送方昵称
	values[kNIMChatRoomMsgKeyType] = msg_type;				//消息类型(NIMChatRoomMsgType)
	values[kNIMChatRoomMsgKeyAttach] = attach;				//消息内容,json结构(发送时要求传入的是非格式化的)
	values[kNIMChatRoomMsgKeyClientMsgid] = client_msg_id;	//客户端消息id
	values[kNIMChatRoomMsgKeyResendFlag] = 0;				//消息重发标记位,第一次发送0,重发1
	values[kNIMChatRoomMsgKeyExt] = ext;					//第三方扩展字段,  json结构(发送时要求传入的是非格式化的)

	nim_chatroom_send_msg func = (nim_chatroom_send_msg) GetProcAddress(hInst, "nim_chatroom_send_msg");

	Json::FastWriter fw;
	func(room_id, fw.write(values).c_str(), "");
}

发送消息状态通过进入聊天室前注册的全局回调获取。

C++

c++void OnSendMsgCallback(__int64 room_id, int error_code, const ChatRoomMessage& result)
{
	if (error_code != 200)
	{

	}
}

void foo()
{
	ChatRoom::RegSendMsgAckCb(&OnSendMsgCallback);
}

C#

c#void ChatRoomApi_SendMessageHandler(long roomId, NIM.ResponseCode code, NIMChatRoom.Message message)
{
	if (code != NIM.ResponseCode.kNIMResSuccess)
	{
		MessageBox.Show("聊天室消息发送失败");
	} 
}

void foo()
{
	NIMChatRoom.ChatRoomApi.SendMessageHandler += ChatRoomApi_SendMessageHandler;
}

C

cstatic void CallbackSendMsgAck(__int64 room_id, int error_code, const char *result, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_reg_send_msg_ack_cb)(const char *json_extension, nim_chatroom_sendmsg_arc_cb_func cb, const void *user_data);

void foo()
{
	nim_chatroom_reg_send_msg_ack_cb func = (nim_chatroom_reg_send_msg_ack_cb) GetProcAddress(hInst, "nim_chatroom_reg_send_msg_ack_cb");
	func(nullptr, &CallbackSendMsgAck, nullptr);
}
  • 接收消息

进入聊天室前注册好接收消息的全局回调函数。

C++

c++void OnReceiveMsgCallback(__int64 room_id, const ChatRoomMessage& result)
{

}
		
void foo()
{
	ChatRoom::RegReceiveMsgCb(&OnReceiveMsgCallback);
}

C#

c#void ChatRoomApi_ReceiveMessageHandler(long roomId, NIMChatRoom.Message message)
{
	string item = string.Format("{0}:\r\n{1}\r\n", message.SenderNickName, message.MessageAttachment);
}

void foo()
{
	NIMChatRoom.ChatRoomApi.ReceiveMessageHandler += ChatRoomApi_ReceiveMessageHandler;
}

C

c++static void CallbackReceiveMsg(__int64 room_id, const char *content, const char *json_extension, const void *user_data)
{

}

typedef void(*nim_chatroom_reg_receive_msg_cb)(const char *json_extension, nim_chatroom_receive_msg_cb_func cb, const void *user_data);

void foo()
{
	nim_chatroom_reg_receive_msg_cb func = (nim_chatroom_reg_receive_msg_cb) GetProcAddress(hInst, "nim_chatroom_reg_receive_msg_cb");
	func(nullptr, &CallbackReceiveMsg, nullptr);
}

查询消息历史

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

C++

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#

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

C

ctypedef 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);
}

根据标签查询历史消息

根据标签(Tags)在云端查询聊天室的历史消息。

以 fromTime 和 toTime(单位毫秒)为时间戳,选择查询方向,指定一种或多种标签和消息类型,往前或者往后拉取 limit 条消息。

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

C++

通过调用 GetMessageHistoryByTagsOnlineAsync 方法根据标签(Tags)在云端查询聊天室的历史消息。

原型:

c++/**
 * @brief 根据消息关联的标签查询历史消息

 * @param[in] room_id           聊天室 ID
 * @param[in] parameters        查询参数
 * @param[in] callback          回调函数
 * @param[in] json_extension    json扩展参数(备用,目前不需要)
 * @return void 无返回值
 */
static void GetMessageHistoryByTagsOnlineAsync(const int64_t room_id,
    const ChatRoomGetMsgHistoryByTagsParameters& parameters,
    const GetMsgHistoryCallback& callback,
    const std::string& json_extension = "");

参数说明:

参数 类型 说明
room_id int64_t 聊天室 ID
tags_ std::list<std::string> 标签列表,支持传入多个标签同时查询
msg_types_ NIMChatRoomMsgType 消息类型列表,查询指定消息类型的消息,默认查询全部消息类型
start_timetag_ int64_t 起始时间,单位毫秒
end_timetag_ int64_t 结束时间,单位毫秒
limit_ int 可查询的最大消息数量
reverse_ bool 查询方向,逆序或者顺序

示例代码:

int64_t room_id = 3001;
ChatRoom::GetMessageHistoryByTagsOnlineAsync(room_id,
	[this](int64_t room_id, int error_code, const std::list<ChatRoomMessage>& messages) {
		if (error_code != nim::kNIMResSuccess)
			return;
		// ...
	});
C

通过调用 get_msg_history_by_tags_online_async 方法根据标签(Tags)在云端查询聊天室的历史消息。

/**
 * @brief 根据发送消息时绑定的标签查询历史消息

 * @param int64_t room_id       聊天室 ID
 * @param parameters_json_str   查询参数格式
 * {"tags":["abc","bcd","def"],"limit":10,"start":0,"end":1665542603510,"reverse":false,"message_types":[0,1,2,3,4,5,6]}
 * @param json_extension        json 扩展参数(备用,目前不需要)
 * @param cb                    回调函数, 定义见nim_chatroom_def.h
 * @param user_data             APP 的自定义用户数据,SDK 只负责传回给回调函数 cb,不做任何处理!
 * @return void 无返回值
 */
NIM_SDK_DLL_API void nim_chatroom_get_msg_history_by_tags_online_async(const int64_t room_id, 
    const char* parameters_json_str,
    const char* json_extension,
    nim_chatroom_get_msg_cb_func cb,
    const void* user_data);

示例代码如下:

C 接口使用 JSON 数据传参,您可以参考以下硬编字符串组织 JSON 数据格式。

c++void query_messages_by_tags_callback(int64_t room_id, int error_code, const char* result, const char* json_extension, const void* user_data) {
	// ...
}

long long room_id = 3001;
char query_parameter[] = R"({
    "tags": ["abc", "def"],
    "start": 0,
    "end": 1666606849508,
    "limit": 100,
    "reverse": false,
    "msgtypes": [0, 1]
})";
nim_chatroom_get_msg_history_by_tags_online_async(room_id,query_parameter, "" ,query_messages_by_tags_callback, NULL);

获取聊天室在线成员

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

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

C++

c++void OnGetMembersCallback(__int64 room_id, int error_code, const std::list<ChatRoomMemberInfo>& infos)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	ChatRoomGetMembersParameters member_param;
	member_param.type_ = kNIMChatRoomGetMemberTypeSolid;
	ChatRoom::GetMembersOnlineAsync(room_id, member_param, &OnGetMembersCallback);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueryMembersOnline(roomId, NIMChatRoom.NIMChatRoomGetMemberType.kNIMChatRoomGetMemberTypeSolid, 0, 10, (room_Id, errorCode, Mmembers) =>
	{

	});
}

C

ctypedef void(*nim_chatroom_get_members_online_async)(const __int64 room_id, const char *parameters_json_str, const char *json_extension, nim_chatroom_get_members_cb_func cb, const void *user_data);

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

}

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

	Json::Value values;
	values[kNIMChatRoomGetMembersKeyType] = type_;					//成员类型
	values[kNIMChatRoomGetMembersKeyOffset] = timestamp_offset_;	//成员时间戳偏移量
	values[kNIMChatRoomGetMembersKeyLimit] = limit_;				//数量

	Json::FastWriter fw;

	func(room_id, fw.write(values).c_str(), nullptr, &CallbackGetMembersOnline, nullptr);
}
  • 获取指定id的在线成员信息

C++

c++void OnGetMembersCallback(__int64 room_id, int error_code, const std::list<ChatRoomMemberInfo>& infos)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	std::list<std::string> ids;
	ids.push_back("user_id");
	ChatRoom::GetMemberInfoByIDsAsync(room_id, ids, &OnGetMembersCallback);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueryMemberInfosByIdCollection(roomId, new string[] { "userID"}, (room_Id, errorCode, Mmembers) =>
	{

	});
}

C

ctypedef void(*nim_chatroom_get_members_by_ids_online_async)(const __int64 room_id, const char *ids_json_array_string, const char *json_extension, nim_chatroom_get_members_cb_func cb, const void *user_data);

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

}

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

	func(room_id, ids, nullptr, &CallbackGetMembersOnline, nullptr);
}

踢出在线成员

C++

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#

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

C

ctypedef 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++

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#

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

ctypedef 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);
}

设置普通成员

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

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

拉黑

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

c++values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeBlackList;	
//拉黑true,取消拉黑false
values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;

禁言

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

c++values[kNIMChatRoomSetMemberAttributeKeyAttribute] = kNIMChatRoomMemberAttributeMuteList;	
//禁言true,取消禁言false	
values[kNIMChatRoomSetMemberAttributeKeyOpt] = true;

临时禁言

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

C++

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#

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

C

cvoid 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);
}

聊天室队列服务

  • 新加(更新)麦序队列元素(聊天室管理员权限)

C++

c++void QueueOfferCallback(int64_t room_id, int error_code)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	ChatRoomQueueElement element;
	element.key_ = "key";
	element.value_ = "value";
	ChatRoom::QueueOfferAsync(room_id, element, &QueueOfferCallback);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueueOfferAsync(roomId, "key", "value", (room_id, error_code, json_extension, user_data) =>
	{
	});
}

C

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

}

typedef void(*nim_chatroom_queue_offer_async)(const int64_t room_id, const char *element_key, const char *element_value, const char *json_extension, nim_chatroom_queue_offer_cb_func cb, const void *user_data);

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

	func(room_id, "key", "value", nullptr, &CallbackQueueOffer, nullptr);
}
  • 取出麦序头元素(聊天室管理员权限)

C++

c++void CallbackQueuePoll(int64_t room_id, int error_code, const ChatRoomQueueElement& element)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	ChatRoom::QueuePollAsync(room_id, "key", &CallbackQueuePoll);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueuePollAsync(roomId, "key", (room_id, error_code, result, json_extension, user_data) =>
	{
	
	});
}

C

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

typedef void(*nim_chatroom_queue_poll_async)(const int64_t room_id, const char *element_key, const char *json_extension, nim_chatroom_queue_poll_cb_func cb, const void *user_data);

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

	func(room_id, "key", nullptr, &CallbackQueuePoll, nullptr);
}
  • 排序列出所有麦序元素

C++

c++void CallbackQueueList(int64_t room_id, int error_code, const ChatRoomQueue& queue)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	ChatRoom::QueueListAsync(room_id, &CallbackQueueList);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueueListAsync(roomId, (room_id, error_code, result, json_extension, user_data) =>
	{
		if (error_code == ResponseCode.kNIMResSuccess)
		{
	
		}
	});
}

C

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

typedef void(*nim_chatroom_queue_list_async)(const int64_t room_id, const char *json_extension, nim_chatroom_queue_list_cb_func cb, const void *user_data);

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

	func(room_id, nullptr, &CallbackQueueList, nullptr);
}
  • 删除麦序队列(聊天室管理员权限)

C++

c++void CallbackQueueDrop(int64_t room_id, int error_code)
{
	if (error_code != nim::kNIMResSuccess)
		return;
}

void foo()
{
	ChatRoom::QueueDropAsync(room_id, &CallbackQueueDrop);
}

C#

c#void foo()
{
	NIMChatRoom.ChatRoomApi.QueueDropAsync(roomId, (room_id, error_code, json_extension, user_data) =>
	{
	
	});
}

C

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

}

typedef void(*nim_chatroom_queue_drop_async)(const int64_t room_id, const char *json_extension, nim_chatroom_queue_drop_cb_func cb, const void *user_data);

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

	func(room_id, nullptr, &CallbackQueueDrop, nullptr);
}

聊天室定向消息

传统聊天室场景一个人发送的消息将广播给所有人或设定的某个标签下所有人(聊天室 SDK 8.4.0 新增的聊天室标签功能)。但在某些场景下,我希望该消息仅发送给聊天室的指定人而不是所有,您可以使用聊天室定向消息能力。

要发送一个定向消息,您可以在发送消息时指定接收消息的用户列表,如下代码所示:

c++// 创建消息属性设置结构体
nim_chatroom::ChatRoomMessageSetting setting;
// 添加要定向发送的 Account ID 列表
settings.to_accids.push_back("receiver01");
settings.to_accids.push_back("receiver02");
settings.to_accids.push_back("receiver03");
std::string msg = nim_chatroom::ChatRoom::CreateRoomMessage(
    msg_type,
    msg_id,
    msg_attach,
    msg_body,
    setting,        // 创建聊天室消息时指定消息设置字段
    0,
    sub_type,
    notify_tag
);
nim_chatroom::ChatRoom::SendMsg(room_id_, msg);

聊天室空间消息

SDK 在 8.11.0 中新增了空间消息能力,用于在部分基于空间坐标的场景下给指定范围内的用户发送消息,如某游戏地图内指定范围的区域。要使用空间消息能力,您首先需要在加入聊天室时开启空间消息开关,并预设一个坐标位置来加入房间,如下代码所示:

c++nim_chatroom::ChatRoomEnterInfo info;
// 开启空间消息能力
info.EnableLocation(true);
nim_chatroom::NIMChatRoomLocation location = {0};
location.x_ = 10;   // 您所在空间位置的 x 坐标
location.y_ = 10;   // 您所在空间位置的 y 坐标
location.z_ = 10;   // 您所在空间位置的 z 坐标
location.distance_ = 100;   // 您要订阅多远距离的消息
info.SetLocation(location); // 应用位置信息到设置中
nim_chatroom::ChatRoom::Enter(room_id_, "your chatroom token", info);

开启空间消息开关并设置了最初的坐标信息后,您可能需要动态去更新该坐标,比如游戏中任务不断移动时需要动态更新坐标,您可以通过调用 nim_chatroom::ChatRoom::UpdateLocation 接口来动态更新位置信息:

c++nim_chatroom::NIMChatRoomLocation location = {0};
location.x_ = 20;
location.y_ = 20;
location.z_ = 20;
location.distance_ = 100;
nim_chatroom::ChatRoom::UpdateLocation(room_id_, location, [](int64_t room_id, int error_code) {
    // result callback
});

同样,在发送消息时,您依然可以携带一个位置信息:

c++// 设置发送消息时携带的坐标信息
nim_chatroom::ChatRoomMessageSetting setting;
setting.location_.x_ = posX;
setting.location_.y_ = posY;
setting.location_.z_ = posZ;
auto msg = nim_chatroom::ChatRoom::CreateRoomMessage(
    msg_type,
    msg_id,
    msg_attach_u,
    msg_body_u,
    setting,            // 指定消息设置信息
    0,
    sub_type,
    notify_tag
);
nim_chatroom::ChatRoom::SendMsg(room_id_, msg);
此文档是否对你有帮助?
有帮助
去反馈
  • 聊天室功能概述
  • 代理设置
  • API原型
  • 参数说明
  • 返回值说明
  • 进入聊天室
  • 聊天室多端登录
  • 离开聊天室(被踢)
  • 聊天室连接情况通知
  • 获取/更新聊天室信息
  • 更新自己的信息
  • 聊天室消息收发
  • 查询消息历史
  • 根据标签查询历史消息
  • 获取聊天室在线成员
  • 踢出在线成员
  • 聊天室权限设置
  • 设置管理员
  • 设置普通成员
  • 拉黑
  • 禁言
  • 临时禁言
  • 聊天室队列服务
  • 聊天室定向消息
  • 聊天室空间消息