实现圈组消息收发
更新时间: 2024/08/22 17:21:31
圈组是网易云信 IM 即时通讯服务的全新能力,可用来帮助您快速构建 “类 Discord 即时通讯社群”。
本文介绍如何通过较少的代码集成 NetEase IM SDK (以下简称 NIM SDK)并调用 API,在您的应用中实现圈组消息收发。
使用前准备
- 已在云信控制台创建应用,获取 App Key。
- 已注册云信 IM 账号,获取 IM 账号和 token。
- 已在云信控制台开通和配置圈组功能。
- NIM SDK 兼容的系统包括 Windows 7、Windows 8/8.1、Windows 10、macOS 10.10(仅支持 x86_64 架构,不支持 i386)。
实现流程
流程概览
实现圈组收发的流程,可分为下图所示的 4 大步骤。
圈组服务端与圈组服务器是两个不同概念,前者指云信服务端提供圈组功能的部分,后者为圈组的特殊概念,对应 Discord 的 Server, 为社群本身,具体参见圈组主要概念。
步骤 1:集成 SDK
为降低接入成本,NetEase IM SDK (以下简称 NIM SDK)C++ 封装层使用 CMake 进行管理,根据不同的情况您在接入 C++ 封装层时可能需要适当的修改,新的发布目录拆分为如下结构:
├─bin
├─include
├─lib
└─wrapper
bin/lib
目录存放 NIM SDK 的动态库文件, 在您发布时请打包使用到的模块,lib
后缀为 Windows 下的动态库符号链接文件(lib)nim(.dll|.so|.dylib)
:即时通讯, 含圈组(lib)nim_chatroom(.dll|.so|.dylib)
: 聊天室(lib)h_available(.dll|.so|.dylib)
: 高可用模块, 被以上两个模块所依赖(lib)nim_tools_http(.dll|.so|.dylib)
: http 工具库,若不使用wrapper/nim_tools_cpp_wrapper/nim_tools_http_cpp.h
中的接口可去除nim_audio.dll
: 音频解码库,仅支持 Windows 环境,若不使用wrapper/nim_tools_cpp_wrapper/nim_audio_cpp.h
中的接口可去除nrtc.dll
: 音视频通话库,仅支持 Windows 环境,若不使用wrapper/nim_cpp_wrapper/api/nim_cpp_vchat.h
中的接口可去除node-nim.node
: NIM SDK Node 封装层, 用于 Electron 以及 Node.js 环境下的接入,其他情况可去除- 其他如
msvcp120.dll
、msvcr120.dll
等(系统)依赖
include
目录存放了 NIM C SDK 的导出头文件wrapper
目录存放了 C++ 封装层的源代码
如果您仅使用 V10 接口,只需将 include
目录添加到头文件搜索路径,代码中包含对应头文件即可使用,无需进行以下步骤。
这里主要介绍以 CMake 工程接入的方式,更多接入方式(包括 VS、Qt、Xcode等传统方式)请参见[集成 SDK](https://doc.yunxin.163.com/messaging2/guide/zQ3MzQyMzQ?platform=client)。
-
使用
add_subdirectory
命令将wrapper
目录添加为子目录。 -
使用
include_directories
方法将include
和wrapper
文件夹添加为头文件搜索路径。 -
根据您的执行目标使用
target_link_libraries
按需添加链接库即可。链接库如下:nim_cpp_wrapper
NIM C++ 封装层库nim_chatroom_cpp_wrapper
Chatroom C++ 封装层库nim_wrapper_util
NIM 及 Chatroom C++ 封装层库通用的工具库nim_tools_cpp_wrapper
NIM HTTP 组件 C++ 封装层库nim_qchat_cpp_wrapper
NIM QChat 圈组 C++ 封装层库
- 不建议将 CMake 产生的工程文件直接引用到项目中使用,因为 CMake 使用将绝对路径写入到工程的配置文件(
.vcxproj
)中,您在自己设备上生成的工程文件无法在其他设备中顺利编译。 - 如果您的工程项目已经是基于 CMake 管理,则只需将
wrapper
工程作为您主项目的依赖即可,其他无需任何多余配置。如果您的工程项目不是基于 CMake 管理的,那么建议您在持续集成(Continuous Integration, CI) 或者与其他同事协作时,通过自定义脚本在项目编译前始终执行 CMake 来生成并编译工程得到需要的二进制文件产物。
示例代码如下:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(nim_demo)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include
${CMAKE_CURRENT_LIST_DIR}/wrapper)
add_subdirectory(wrapper)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME}
nim_cpp_wrapper
nim_chatroom_cpp_wrapper
nim_wrapper_util
nim_tools_cpp_wrapper
nim_qchat_cpp_wrapper)
步骤 2:初始化 SDK
将 SDK 集成到客户端后,需要先完成 SDK 的初始化才能使用其他功能。
-
引入 SDK 动态库文件。
将 V10 NIM SDK 提供了不同平台的动态库文件,不同平台下的区别如下:
- Windows 下后缀为 .dll,您需要将动态库文件放置到应用程序相同目录。
- macOS 下后缀为 .dylib,您需要在打包应用时将 .dylib 文件放置到 YouApp.app/Contents/Frameworks 目录下。
- Linux 下后缀为 .so,与 Windows 一样与应用程序放置到同一个目录下即可。
Windows SDK 基于 MSVC15(2017) 开发,如果 App 没有对应的运行时库文件,请在安装应用时部署微软提供的 MSVC 2017 运行时库组件。
-
调用
init
方法初始化 SDK,推荐在应用程序启动时初始化。初始化成功后,即可使用 V10 所有的 API。int main(int argc, char* argv[]) { v2::V2NIMInitOption option; auto error = v2::V2NIMClient::get().init(option); if (error) { // handle error return -1; } error = v2::V2NIMClient::get().uninit(); if (error) { // handle error return -1; } return 0; }
更多初始化相关说明,请参见初始化 SDK。
步骤 3:登录 IM
客户端用户在使用云信即时通讯功能前需要先登录云信 IM 服务器。
V10 已采用融合登录方案,用户只需要调用 V2NIMLoginService#login
方法登录一次,则可以同时使用 IM 与圈组,无需再单独登录圈组服务器。
调用 V2NIMLoginService#login
后调用 Login
方法将会报错。
以静态 Token 登录为例,示例代码如下:
cppV2NIMLoginOption option;
loginService.login(
"accountId",
"token",
option,
[]() {
// login succeeded
},
[](V2NIMError error) {
// login failed, handle error
});
其他登录方式请参见登录登出 IM。
步骤 4:圈组消息收发
本节以发送方与接收方的消息交互为例,介绍在不考虑用户权限管理的情况下,使用 SDK API 快速实现圈组文本消息收发的流程。
-
接收方在登录圈组之前,调用
RegRecvCb
方法监听消息接收。cpp
QChatRegRecvMsgCbParam reg_receive_message_cb_param; reg_receive_message_cb_param.cb = [this](const QChatRecvMsgResp& resp) { if (resp.res_code != NIMResCode::kNIMResSuccess) { // error handling return; } // process response // ... }; Message::RegRecvCb(reg_receive_message_cb_param);
-
发送方调用
CreateServer
方法创建圈组服务器。为更加快速实现消息收发,创建时可将invite_mode
设置为kNIMQChatServerApplyModeNormal
(发送邀请后,不需要被邀请方同意,被邀请方立即加入服务器)。cpp
QChatServerCreateParam param; param.server_info.name = "server name"; param.server_info.invite_mode = kNIMQChatServerApplyModeNormal; param.server_info.apply_mode = kNIMQChatServerApplyModeNormal; param.cb = [this](const QChatServerCreateResp& resp) { if (resp.res_code != NIMResCode::kNIMResSuccess) { // error handling return; } // process response // ... }; Server::CreateServer(param);
-
发送方调用
CreateChannel
方法,调用时传入上一步中创建的圈组服务器的server_id
,且将view_mode
和type
分别设置为公开模式(kNIMQChatChannelViewModePublic
)和文本消息频道(kNIMQChatChannelTypeText
),从而在圈组服务器中创建一个文本消息类型的公开频道。cpp
QChatChannelCreateParam param; param.channel_info.server_id = 123456; param.channel_info.name = "channel name"; param.channel_info.type = kNIMQChatChannelTypeText; param.channel_info.view_mode = kNIMQChatChannelViewModePublic; param.cb = [this](const QChatChannelCreateResp& resp) { if (resp.res_code != NIMResCode::kNIMResSuccess) { // error handling return; } // process response // ... }; Channel::CreateChannel(param);
-
发送方调用
Invite
方法,邀请接收方加入服务器。cpp
QChatServerInviteParam param; param.server_id = 123456; param.invite_ids = {"accid1", "accid2"}; param.postscript = "your postscript"; param.cb = [this](const QChatServerInviteResp& resp) { if (resp.res_code != NIMResCode::kNIMResSuccess) { // error handling return; } // process response // ... }; Server::Invite(param);
-
发送方调用
Send
方法,调用时传入服务器与公开频道的ID,从而在公开频道中发送一条消息。示例代码如下:
cpp
QChatSendMessageParam param; param.message.server_id = 123456; // Specify the ID of the server. param.message.channel_id = 123456; // Specify the ID of the channel. param.message.msg_body = "message body"; // Specify the content of the message. param.message.resend_flag = false; // Specify whether to resend the message. param.message.msg_id = ""; // Only for resending the message. If not required, leave it empty, the SDK will generate it by default. param.message.history_enable = false; // Specify whether to enable cloud storage for the message. // text message param.message.msg_type = kNIMQChatMsgTypeText; auto attach = std::make_shared<QChatDefaultAttach>(); attach->msg_attach = "msg attach"; Message::Send(param);
-
接收方通过该回调(
onRecvMessages
)接收消息(QChatMessage
)。
后续步骤
为保障通信安全,如果您在调试环境中的使用的是云信控制台生成的测试用 IM 账号 和 token
,请确保在后续的正式生产环境中,将其替换为通过 IM 新版服务端 API 生成的正式 IM 账号和 token
。