logo
当前页

收发消息


功能简介

ZIM SDK 支持单聊消息、群组消息、房间消息等的收发,以及查询历史消息、删除消息等功能。可广泛应用于娱乐社交、电商购物、在线教育、互动直播等多种场景下。

本文档介绍了如何使用 ZIM SDK 的接口,实现各类消息的收发功能与监听消息的状态。

说明

开发者请根据业务需要,查看 查询历史消息删除消息 等功能。

消息类型

目前 ZIM 支持的消息类型如下:

消息类型说明特性及适用场景
ZIMCommandMessage(2)开发者可自定义数据内容的信令消息。消息大小不超过 5 KB,单个客户端发送频率限制为 10 次/秒。

不可存储,支持更高的并发;一般适用于“语聊房”、“在线课堂”等房间内的信令传输,比如上下麦操作、送礼物,发送在线课堂课件等。

相关接口:sendMessage

ZIMBarrageMessage(20)房间内弹幕文本消息。消息大小不超过 5 KB,单个客户端发送频率无限制。

不可存储,专门用于房间内的高频、不可靠、允许丢掉的消息,一般适用于发送“弹幕消息”的场景中。

支持高并发,但不可靠,不保证消息送达。

相关接口:sendMessage

ZIMTextMessage(1)文本消息。消息大小不超过 32 KB,单个客户端发送频率限制为 10 次/秒。

消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”)。
可用于单聊、房间、群聊等即时聊天场景。房间解散后,“房间聊天”的消息不存储。

  • 图片、文件、语音、视频:通常用于发送富媒体文件类型的消息。
  • 自定义消息:通常用于发送投票类型、接龙类型、视频卡片类型等消息。
  • 组合消息:常用于发送图文消息。

相关接口:sendMessagereplyMessage

ZIMMultipleMessage(10)组合消息,即包含多个 item 的消息,可包括多条文本、至多 10 张图片、1 个文件、1 个音频、1 个视频和 1 条自定义消息。
说明
  • Item 总量不得超过 20。
  • 图片、音频、文件和视频的大小和格式限制与对应的富媒体消息类型相同。
ZIMImageMessage(11)图片消息。支持主流图片格式,包括 JPG、PNG、BMP、TIFF、GIF、WebP,大小不超过 10 MB,单个客户端发送频率限制为 10 次/秒。
ZIMFileMessage(12)文件消息。消息内容为文件,格式不限,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。
ZIMAudioMessage(13)语音消息。支持 MP3、M4A 格式的语音文件,时长不超过 300 秒,大小不超过 6 MB,单个客户端发送频率限制为 10 次/秒。
ZIMVideoMessage(14)视频消息。支持 MP4、MOV 格式的视频文件,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。
说明
若要在消息发送成功后获取视频首帧的宽高信息,视频必须使用 H.264 或 H.265 编码格式。
ZIMCombineMessage(100)合并消息,消息大小无限制,单个客户端发送频率限制为 10 次/秒。
ZIMCustomMessage(200)自定义消息。开发者可自定义消息的类型,并自行完成消息的解析,ZIM SDK 不负责定义和解析自定义消息的具体内容。

收发普通消息

普通消息,包含 ZIMTextMessage、ZIMBarrageMessage 等消息类型。

注意
  • 开发者可以通过注册 setEventHandler 监听,用于接收相关通知(接收房间消息、连接状态、token 即将过期等通知)。
  • 接收消息时,收到的消息类型是基类 ZIMMessage 。开发者需要根据其中的 type(具体请参考 ZIMMessageType )字段,判断消息类型是 Text 还是 Command,然后强转基类为具体的子类( ZIMTextMessageZIMCommandMessage ),然后从 “message” 字段获取消息内容。
  • 接收消息时,可以使用消息的 orderkey 来实现排序;即 orderkey 越大,消息的时间越新。接收到消息后,会自动更新消息未读数量。

发送消息

以客户端 A 向客户端 B 发送消息为例:

  1. 客户端 A、B 分别创建自己的 ZIM 实例,并注册 setEventHandler 监听的 onPeerMessageReceived 回调接口,用于接收单聊消息通知。
  2. 客户端 A、B 分别登录 ZIM SDK。
  3. 客户端 A 调用 sendMessage 接口,设置 conversationTypeZIMConversationType.Peer 发送一条单聊消息到客户端 B。
  4. 客户端 B 将通过 onPeerMessageReceived 回调接口,收到客户端 A 的消息。
注意

目前 ZIM 不支持调用 sendMessage 接口,向自己发送消息(即 toConversationID = 自己的 ID)。如果尝试向自己发送消息,会返回错误 6000001,并提示传入参数错误。

示例代码
// 发送单聊 `Text` 信息

zim::ZIMMessage* message = nullptr;
zim::ZIMTextMessage text_message;
text_message.message = "message";
// 设置消息优先级
zim::ZIMMessageSendConfig config;
config.priority = zim::ZIM_MESSAGE_PRIORITY_LOW;
message = &text_message;

zim::ZIMConversationType type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { int i = 0; });

zim_->sendMessage(message, "toConversationID", type, config, notification,
                    [=](const std::shared_ptr<zim::ZIMMessage> &message,
                              const zim::ZIMError &errorInfo) { int i = 0; });
1
Copied!

接收消息

说明
Untitled
// 收到单聊消息的回调
void onPeerMessagedReceived(ZIM *zim*,
                         const std::vector<std::shared_ptr<ZIMMessage>> & messageList,
                         const ZIMMessageReceivedInfo & info,
                         const std::string &fromUserID) {
    //在此编写收到消息后的业务逻辑
}

// 收到群组消息的回调
void onGroupMessagedReceived(ZIM *zim*,
                         const std::vector<std::shared_ptr<ZIMMessage>> & messageList,
                         const ZIMMessageReceivedInfo & info,
                         const std::string &fromGroupID) {
    //在此编写收到消息后的业务逻辑
}

// 收到房间消息的回调
void onRoomMessagedReceived(ZIM *zim*,
                         const std::vector<std::shared_ptr<ZIMMessage>> & messageList,
                         const ZIMMessageReceivedInfo & info,
                         const std::string &fromRoomID) {
    //在此编写收到消息后的业务逻辑
}
1
Copied!

收发富媒体消息

ZIM SDK 支持发送多种类型的富媒体消息,包含图片、文件、音频、视频等消息类型,开发者可以通过以下步骤实现富媒体文件消息的收发。

  1. 用户登录成功后,指定消息类型(图片、文件、音频、视频)、会话类型(单聊、房间、群组)等,向指定会话发送富媒体消息。
  2. 接收方用户登录成功后,根据会话类型(单聊、房间、群组)的相关回调监听,接收富媒体消息的相关通知,以及下载富媒体消息文件到本地。

发送富媒体消息

用户登录成功后,调用 sendMessage 接口,指定会话、消息类型(图片、文件、音频、视频)、会话类型(单聊、房间、群组)、以及相关消息配置,向指定会话发送富媒体消息。

注意
  • 发送富媒体消息时,填写的待发送文件路径,必须使用 UTF-8 编码格式。
  • 如果需要向房间/群组内发送富媒体消息,消息发送者必须要在这个房间/群组内。
图片
文件
音频
视频
// 发送多媒体消息示例 - 单聊 发送图片消息
zim::ZIMMediaMessage *message = nullptr;
auto imageMessage = zim::ZIMImageMessage();

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

// 离线推送标题,需要离线推送时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要离线推送时,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要离线推送带上额外信息时,可酌情填入该字段
pushConfig.extendedData = "win_push_extended_data";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
// 需要离线推送时赋值;如不需要,可赋值为 nullptr
sendConfig.pushConfig = &pushConfig;

// 需填入 UTF-8 格式的本地路径
imageMessage.fileLocalPath = "D:\\image\\img.jpg";
// 如果此处填入了网络 URL,SDK 则会透传该路径,而不会经过 ZIM 后台服务处理。同时填入网络 URL 与本地路径,SDK 会优先认为用户想要使用网络 URL
imageMessage.fileDownloadUrl = "";
imageMessage.largeImageDownloadUrl = "";
imageMessage.thumbnailDownloadUrl = "";

message = &imageMessage;

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { 
                // 开发者可监听此回调,执行消息发送前的逻辑
            },
            [=](const std::shared_ptr<zim::ZIMMediaMessage> &message,
                unsigned long long currentFileSize,
                unsigned long long totalFileSize) { 
                // 开发者可监听此回调,获取资源上传的进度
            });

zim_->sendMessage(message, receiver_id, zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER,
    sendConfig,notification,
    [=](const std::shared_ptr<zim::ZIMMessage> &message, const zim::ZIMError &errorInfo) {
        
    });
1
Copied!
// 发送多媒体消息示例 - 单聊 发送文件消息
zim::ZIMMediaMessage *message = nullptr;
auto fileMessage = zim::ZIMFileMessage();

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

// 离线推送标题,需要离线推送时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要离线推送时,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要离线推送带上额外信息时,可酌情填入该字段
pushConfig.extendedData = "win_push_extended_data";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
// 需要离线推送时赋值;如不需要,可赋值为 nullptr
sendConfig.pushConfig = &pushConfig;

// 需填入 UTF-8 格式的本地路径
fileMessage.fileLocalPath = "D:\\file\\files.zip";
// 如果此处填入了网络 URL,SDK 则会透传该路径,而不会经过 ZIM 后台服务处理。同时填入网络 URL 与本地路径,SDK 会优先认为用户想要使用网络 URL
fileMessage.fileDownloadUrl = "";

message = &fileMessage;

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { 
                // 开发者可监听此回调,执行消息发送前的逻辑
            },
            [=](const std::shared_ptr<zim::ZIMMediaMessage> &message,
                unsigned long long currentFileSize,
                unsigned long long totalFileSize) { 
                // 开发者可监听此回调,获取资源上传的进度
            });

zim_->sendMessage(message, receiver_id, zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER,
    sendConfig,,notification,
    [=](const std::shared_ptr<zim::ZIMMessage> &message, const zim::ZIMError &errorInfo) {
        auto media_message = std::static_pointer_cast<zim::ZIMFileMessage>(message);

        int code = errorInfo.code;
    });
1
Copied!
// 发送多媒体消息示例 - 单聊 发送音频消息
zim::ZIMMediaMessage *message = nullptr;
auto audioMessage = zim::ZIMAudioMessage();

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

// 离线推送标题,需要离线推送时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要离线推送时,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要离线推送带上额外信息时,可酌情填入该字段
pushConfig.extendedData = "win_push_extended_data";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
// 需要离线推送时赋值;如不需要,可赋值为 nullptr
sendConfig.pushConfig = &pushConfig;

// 需填入 UTF-8 格式的本地路径
audioMessage.fileLocalPath = "D:\\audio\\audio.mp3";
// 如果此处填入了网络 URL,SDK 则会透传该路径,而不会经过 ZIM 后台服务处理。同时填入网络 URL 与本地路径,SDK 会优先认为用户想要使用网络 URL
audioMessage.fileDownloadUrl = "";
// 音频时长的单位为 秒
audioMessage.audioDuration = 15;

message = &audioMessage;

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { 
                // 开发者可监听此回调,执行消息发送前的逻辑
            },
            [=](const std::shared_ptr<zim::ZIMMediaMessage> &message,
                unsigned long long currentFileSize,
                unsigned long long totalFileSize) { 
                // 开发者可监听此回调,获取资源上传的进度
            });

zim_->sendMessage(message, receiver_id, zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER,
    sendConfig,notification ,
    [=](const std::shared_ptr<zim::ZIMMessage> &message, const zim::ZIMError &errorInfo) {
        auto media_message = std::static_pointer_cast<zim::ZIMAudioMessage>(message);

        int code = errorInfo.code;
    });
1
Copied!
// 发送多媒体消息示例 - 单聊 发送视频消息
zim::ZIMMediaMessage *message = nullptr;
auto videoMessage = zim::ZIMVideoMessage();

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

// 离线推送标题,需要离线推送时,请填入该字段
pushConfig.title = "win_push_title";
// 离线推送内容,需要离线推送时,请填入该字段
pushConfig.content = "win_push_content";
// 离线推送附加字段,需要离线推送带上额外信息时,可酌情填入该字段
pushConfig.extendedData = "win_push_extended_data";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
// 需要离线推送时赋值;如不需要,可赋值为 nullptr
sendConfig.pushConfig = &pushConfig;

// 需填入 UTF-8 格式的本地路径
videoMessage.fileLocalPath = "D:\\file\\video.mp4";
// 如果此处填入了网络 URL,SDK 则会透传该路径,而不会经过 ZIM 后台服务处理。同时填入网络 URL 与本地路径,SDK 会优先认为用户想要使用网络 URL
videoMessage.fileDownloadUrl = "";
videoMessage.videoFirstFrameDownloadUrl = "";
// 视频时长的单位为 秒
videoMessage.videoDuration = 100;

message = &videoMessage;
auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { 
                // 开发者可监听此回调,执行消息发送前的逻辑
            },
            [=](const std::shared_ptr<zim::ZIMMediaMessage> &message,
                unsigned long long currentFileSize,
                unsigned long long totalFileSize) { 
                // 开发者可监听此回调,获取资源上传的进度
            });

zim_->sendMessage(message, receiver_id, zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER,
    sendConfig,notification,
    [=](const std::shared_ptr<zim::ZIMMessage> &message, const zim::ZIMError &errorInfo) {
        auto media_message = std::static_pointer_cast<zim::ZIMVideoMessage>(message);

        int code = errorInfo.code;
    });
1
Copied!

富媒体文件消息的发送进度回调

开发者可以通过 onMediaUploadingProgress 回调,接收富媒体消息的上传发送进度的相关通知。

Untitled
using ZIMMediaUploadingProgress = std::function<void(const std::shared_ptr<ZIMMediaMessage> &message, long long currentSize, long long totalSize)>;
1
Copied!

其中:

  • message:正在发送消息的内容。
  • currentFileSize:当前已被发送的消息大小。
  • totalFileSize:发送消息的总体大小。

接收富媒体消息

接收方用户登录成功后,根据会话类型(单聊、房间、群组)的相关回调监听( onPeerMessageReceivedonRoomMessageReceivedonGroupMessageReceived ),接收富媒体消息的相关通知,然后可以直接获取富媒体消息的相关 URL 属性。

如需下载富媒体消息到本地,可调用 downloadMediaFile 接口。

下载富媒体消息时,需要指定对应的媒体消息的文件类型。

  • 图片消息:可以选择下载原始文件、大图、缩略图。
  • 文件/音频消息:仅能选择下载文件/音频的原始文件。
  • 视频消息:可以选择下载视频原始文件、视频首帧的缩略图。
Untitled
// 接收富媒体消息示例 - 单聊
void onPeerMessageReceived(
    zim::ZIM *zim, const std::vector<std::shared_ptr<zim::ZIMMessage>> &messageList,
    const ZIMMessageReceivedInfo &info,
    const std::string &fromUserID) {
    
    zim::ZIMMediaDownloadConfig download_config;

    for (auto &it : messageList) {
        // 收到消息时,可通过消息的 Type 进行判断接收到何种类型的消息
        if (it->getType() == zim::ZIMMessageType::ZIM_MESSAGE_TYPE_IMAGE) {
            // Image message type
            auto image_message = std::dynamic_pointer_cast<zim::ZIMImageMessage>(it);

            // 下载原图示例如下,如果想下载其他类型,可以换用其他 ZIMMediaFileType
            zim_->downloadMediaFile(
                image_message.get(),
                zim::ZIMMediaFileType::ZIM_MEDIA_FILE_TYPE_ORIGINAL_FILE,
                download_config,
                [=](const std::shared_ptr<zim::ZIMMessage> &message, unsigned int currentSize,
                    unsigned int totalSize) {

                },
                [=](const std::shared_ptr<zim::ZIMMessage> &message,
                    const zim::ZIMError &errorInfo) {

                });
            ...
        } else if (it->getType() == zim::ZIMMessageType::ZIM_MESSAGE_TYPE_FILE) {
            //  文件消息
            auto media_message = std::dynamic_pointer_cast<zim::ZIMFileMessage>(it);
            ...
        } else if (it->getType() == zim::ZIMMessageType::ZIM_MESSAGE_TYPE_AUDIO) {
            // 音频消息
            auto media_message = std::dynamic_pointer_cast<zim::ZIMAudioMessage>(it);
            ...
        } else if (it->getType() == zim::ZIMMessageType::ZIM_MESSAGE_TYPE_VIDEO) {
            // 视频消息
            auto media_message = std::dynamic_pointer_cast<zim::ZIMVideoMessage>(it);
            ...
        }
    }

}
1
Copied!

富媒体文件消息的下载进度回调

开发者可以通过 ZIMMediaDownloadingProgress 回调,接收富媒体消息的下载进度的相关通知。

Untitled
using ZIMMediaDownloadingProgress = std::function<void(const std::shared_ptr<ZIMMessage> &message, unsigned int currentSize, unsigned int totalSize)>;
1
Copied!

其中:

  • message:正在下载的消息内容。
  • currentFileSize:当前已被下载的消息大小。
  • totalFileSize:下载消息的总体大小。

收发信令消息

ZIM SDK 支持开发者实现信令类型的消息收发,开发者可以通过 ZIMCommandMessage 对象定义自己的消息类型,例如位置消息等。

说明

信令消息不支持离线推送和本地存储。

以下以向指定用户发送信令消息为例。

发送信令消息

Untitled
// 向指定用户发送信令消息
zim::ZIMMessage *message = nullptr;
zim::ZIMCommandMessage commandMessage;

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

pushConfig.content = "win_push_content";
pushConfig.extendedData = "win_push_extended_data";
pushConfig.title = "win_push_title";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
sendConfig.pushConfig = &pushConfig;

std::vector<uint8_t> uint8Message;
uint8Message.assign(strMessage.begin(), strMessage.end());
commandMessage.message = uint8Message;

message = &commandMessage;

// 发送单聊信息 
zim::ZIMConversationType type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER

// 发送群聊信息
// zim::ZIMConversationType type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_GROUP

// 发送房间信息
// zim::ZIMConversationType type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_ROOM

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { int i = 0; });

// 发送消息
zim_->sendMessage(message, "toConversationID", type, config, notification,
                    [=](const std::shared_ptr<zim::ZIMMessage> &message,
                              const zim::ZIMError &errorInfo) { int i = 0; });
1
Copied!

接收信令消息

Untitled
//用户接收信令消息
void onPeerMessageReceived(zim::ZIM *zim, const std::vector<std::shared_ptr<zim::ZIMMessage>> &messageList,
    const ZIMMessageReceivedInfo &info, const std::string &fromUserID) {
    for (auto &it : message_list) {
        if (it->getType() == zim::ZIM_MESSAGE_TYPE_COMMAND) {
            auto commandMessage = std::dynamic_pointer_cast<zim::ZIMCommandMessage>(it);
            
        }
    }
}
1
Copied!

收发自定义消息

ZIM SDK 支持开发者实现自定义类型的消息收发,开发者可以通过 ZIMCustomMessage 对象自行定义消息类型,例如投票类型、接龙类型、视频卡片类型等。开发者可以通过以下步骤实现自定义消息的收发。

说明
  • 仅 2.8.0 及以上版本的 ZIM SDK 支持发送自定义类型消息,接收并查看自定义类型消息的内容。
  • 如果接收端的 SDK 版本介乎 [2.0.0, 2.8.0) 区间,可以收到自定义消息时,但会显示此消息类型为未知,且无法获取信息内容。如需获取此条消息,请将 SDK 升级为 2.8.0 或以上版本。
  • 如果接收端的 SDK 版本为 1.x.x 版本,则无法收到自定义消息,也不会收到未知消息。

发送自定义消息

发送自定义消息使用的接口为 sendMessage ,与发送普通消息所用接口相同,开发者可参考 收发普通消息 - 发送消息 了解此接口参数详情。

开发者需要通过 ZIMCustomMessage 对象定义自定义类型消息,包括以下参数:

以下为用户在单聊会话中发送自定义消息的示例代码:

Untitled
// 向指定用户发送自定义消息
zim::ZIMMessage *message = nullptr;
zim::ZIMCustomMessage customMessage;

zim::ZIMMessageSendConfig sendConfig;
zim::ZIMPushConfig pushConfig;

pushConfig.content = "win_push_content";
pushConfig.extendedData = "win_push_extended_data";
pushConfig.title = "win_push_title";

sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
sendConfig.pushConfig = &pushConfig;

std::string message = "message";
unsigned int subType = 1;
std::string searchedContent = "searchedContent";

customMessage.message = message;
customMessage.subType = subType;
customMessage.searchedContent = searchedContent;

message = &customMessage;

zim::ZIMConversationType type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER

auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) { int i = 0; });

zim_->sendMessage(message, "toConversationID", type, config, notification,
                    [=](const std::shared_ptr<zim::ZIMMessage> &message,
                              const zim::ZIMError &errorInfo) { int i = 0; });
1
Copied!

接收自定义消息

接收自定义消息的回调接口与接收普通消息的回调接口一致,请参考 收发普通消息 - 接收消息 了解具体接口。

以下为用户在单聊会话中接收自定义消息的示例代码:

Untitled
//用户接收自定义消息
void onPeerMessageReceived(zim::ZIM *zim, const std::vector<std::shared_ptr<zim::ZIMMessage>> &messageList,
    const ZIMMessageReceivedInfo &info, const std::string &fromUserID) {
    for (auto &it : message_list) {
        if (it->getType() == zim::ZIM_MESSAGE_TYPE_CUSTOM) {
            auto customMessage = std::dynamic_pointer_cast<zim::ZIMCustomMessage>(it);
        }
    }
}
1
Copied!

收发组合消息

ZIM SDK 支持开发者实现组合类型的消息收发,开发者可以通过 ZIMMultipleMessage 对象组合多种消息类型,例如图文类型等。

说明
  • 仅 2.19.0 及以上版本的 ZIM SDK 支持发送组合类型消息,接收并查看组合类型消息的内容。
  • 如果接收端的 SDK 版本介乎 [2.0.0, 2.19.0) 区间,可以收到组合消息时,但会显示此消息类型为未知,且无法获取信息内容。如需获取此条消息,请将 SDK 升级为 2.19.0 或以上版本。
  • 如果接收端的 SDK 版本为 1.x.x 版本,则无法收到组合消息,也不会收到未知消息。

发送组合消息

用户登录成功后,通过 ZIMMultipleMessage 对象组合多种消息类型(文本、图片、音频、视频、文件和自定义文本等),调用 sendMessage 接口向单聊、房间或群聊会话发送该消息。

您可以通过 onMultipleMediaUploadingProgress 回调,接收组合消息中富媒体文件的上传进度的相关通知。在此回调中,您可以了解到以下字段:

  • currentFileSize:已上传文件总大小,单位为 Byte。
  • totalFileSize:组合消息中多媒体文件的总大小,,单位为 Byte。
  • messageInfoIndex:接收到此回调时,当前正在上传的文件在 ZIMMultipleMessage 数组的索引。
  • currentIndexFileSize: 接收到此回调时,当前正在上传的文件的已上传大小,单位为 Byte。
  • totalIndexFileSize:接收到此回调时,当前正在上传的文件的实际大小,单位为 Byte。

上述字段可用于计算多媒体文件的总上传进度、以及当前文档的上传进度:

    • 总上传进度 = currentFileSize / totalFileSize。
    • 当前文件上传进度 = currentIndexFileSize / totalIndexFileSize。
  • 以下为用户在单聊会话中发送组合消息的示例代码:

    Untitled
    // 在单聊会话中向指定用户发送组合消息
    
    auto multiMsg = std::make_shared<ZIMMultipleMessage>();
    
    // 文本
    auto textMsgInfo = std::make_shared<ZIMTextMessageLiteInfo>();
    textMsgInfo->message = "消息内容";
    multiMsg->messageInfoList.push_back(textMsgInfo);
    
    // 自定义消息:最多支持 1 个
    auto customMsgInfo = std::make_shared<ZIMCustomMessageLiteInfo>();
    customMsgInfo->message = "消息内容";
    customMsgInfo->searchedContent = "搜索内容";
    customMsgInfo->subType = 100;
    multiMsg->messageInfoList.push_back(customMsgInfo);
    
    // 图片:最多支持 10 个
    // 网络图片示例
    auto imageMsgInfo = std::make_shared<ZIMImageMessageLiteInfo>();
    imageMsgInfo->fileDownloadUrl = "https://xxxx.jpeg";                // 原图
    imageMsgInfo->thumbnailDownloadUrl = "https://xxxx-thumbnail.jpeg"; // 缩略图
    imageMsgInfo->largeImageDownloadUrl = "https://xxxx-large.jpeg";    // 大图
    multiMsg->messageInfoList.push_back(imageMsgInfo);
    
    // 本地图片示例
    auto localImageMsgInfo = std::make_shared<ZIMImageMessageLiteInfo>();
    localImageMsgInfo->fileLocalPath = "D:\\files\\xxx.jpg"; // 图片的绝对路径
    multiMsg->messageInfoList.push_back(localImageMsgInfo);
    
    // 文件:最多支持 1 个
    auto localFileMsgInfo = std::make_shared<ZIMFileMessageLiteInfo>();
    localFileMsgInfo->fileLocalPath = "D:\\files\\xxx.zip"; // 文件的绝对路径
    multiMsg->messageInfoList.push_back(localFileMsgInfo);
    
    // 音频:最多支持 1 个
    auto localAudioMsgInfo = std::make_shared<ZIMAudioMessageLiteInfo>();
    localAudioMsgInfo->fileLocalPath = "D:\\files\\xxx.mp3"; // 音频的绝对路径
    localAudioMsgInfo->audioDuration = 100; // 必填,音频时长,单位秒
    multiMsg->messageInfoList.push_back(localAudioMsgInfo);
    
    // 视频:最多支持 1 个
    auto localVideoMsgInfo = std::make_shared<ZIMVideoMessageLiteInfo>();
    localVideoMsgInfo->fileLocalPath = "D:\\files\\xxx.mp4"; // 文件绝对路径
    localVideoMsgInfo->videoDuration = 100; // 必填,视频时长,单位秒
    multiMsg->messageInfoList.push_back(localVideoMsgInfo);
    
    zim::ZIMMessageSendConfig sendConfig;
    zim::ZIMPushConfig pushConfig;
    
    pushConfig.content = "win_push_content";
    pushConfig.payload = "win_push_payload";
    pushConfig.title = "win_push_title";
    
    sendConfig.priority = zim::ZIM_MESSAGE_PRIORITY_MEDIUM;
    sendConfig.pushConfig = &pushConfig;
    
    auto type = zim::ZIMConversationType::ZIM_CONVERSATION_TYPE_PEER;
    
    auto notification = std::make_shared<zim::ZIMMessageSendNotification>(
        [=](const std::shared_ptr<zim::ZIMMessage> &message) {
            // 开发者可监听此回调,执行消息发送前的逻辑
        },
        [=](const std::shared_ptr<ZIMMediaMessage> &message,
            unsigned long long currentFileSize, unsigned long long totalFileSize) {
            // 发送组合消息时,该通知不会触发
        },
        [=](const std::shared_ptr<zim::ZIMMultipleMessage> &message,
            unsigned long long currentFileSize, // 已上传文件总大小,单位为 Byte。比如已上传了 20,971,520 Byte,则此处为 20,971,520。
            unsigned long long totalFileSize, // 总文件大小,单位为 Byte。比如总文件大小 104,857,600 Byte,则此处为 104,857,600
            unsigned int messageInfoIndex, // 接收到此回调时,当前正在上传的文件在 messageInfoList 数组的索引
            unsigned long long currentIndexFileSize, // 接收到此回调时,当前正在上传的文件的已上传大小,单位为 Byte。
            unsigned long long totalIndexFileSize // 触发该回调对应的文件的大小
        ) {
            // 发送组合消息的上传回调,如果组合消息中没有媒体类型,则该回调不会触发
        });
    
    zim_->sendMessage(multiMsg, "toConversationID", type, sendConfig, notification,
                        [=](const std::shared_ptr<zim::ZIMMessage> &message,
                            const zim::ZIMError &errorInfo) {
                            // 发送结果的回调
                        });
    
    1
    Copied!

    接收组合消息

    接收组合消息的回调接口与接收普通消息的回调接口一致,请参考 收发普通消息 - 接收消息 了解具体接口。

    以下为用户在单聊会话中接收组合消息的示例代码:

    Untitled
    // 用户接收组合消息
    void onPeerMessageReceived(zim::ZIM *zim, const std::vector<std::shared_ptr<zim::ZIMMessage>> &messageList,
        const ZIMMessageReceivedInfo &info, const std::string &fromUserID) {
        for (auto &it : message_list) {
            if (it->getType() == zim::ZIM_MESSAGE_TYPE_MULTIPLE ) {
                auto multipleMessage = std::dynamic_pointer_cast<zim::ZIMMultipleMessage>(it);
            }
        }
    }
    
    1
    Copied!

    收发 @ 消息

    @ 消息,是指包含“@ + 用户”内容的消息。被 @ 的用户在收到消息时会强提醒。

    说明

    @ 消息不属于消息类型。一条消息既可以是文本消息或其他类型消息,同时也是 @ 消息。

    发送 @ 消息

    在调用 sendMessage 发送消息时,可以通过以下方法(可同时使用)将一条消息设置为 @ 信息:

    • mentionedUserIDs:提醒指定用户(可以是会话外用户)查看消息。传入的 userID 列表长度最多为 50,如需上调,请联系 ZEGO 技术支持。
    • isMentionAll:提醒会话内所有其他用户查看消息。
    说明

    仅 2.14.0 及以上版本的 ZIM SDK 支持发送消息中带 @ 信息。

    Untitled
    // 创建提醒用户列表
    std::vector<std::string> mentionArrayList;
    
    // 添加提醒用户(用户可以不在当前会话)
    mentionArrayList.push_back("userId1");
    mentionArrayList.push_back("userId2");
    
    // message 可以为任何类型消息
    message->mentionedUserIDs = mentionArrayList;
    
    // 提醒会话内所有其他用户查看消息
    bool isMentionAll = true;
    message->isMentionAll = true;
    
    ZIMMessageSendConfig config;
    // 设置消息优先级
    config.priority = ZIMMessagePriority::LOW;
    
    // 是否强推送给被提醒用户(不管对方是否开启了会话免打扰),默认为 false;
    config.isNotifyMentionedUsers = true;
    
    // 以发送单聊信息为例子
    ZIMConversationType type = ZIMConversationType::Peer;
    
    zim_->sendMessage(
        message, "conv_id", type, config,
        std::make_shared<zim::ZIMMessageSendNotification>(
            [=](const std::shared_ptr<zim::ZIMMessage> &message) {
                if (message) {
                    // 开发者可以通过该回调,监听消息是否开始准备发送。只有当通过本地基础参数检验的消息才会抛出该回调,否则通过 onMessageSent 回调抛出错误。
                }
            }),
        [=](std::shared_ptr<zim::ZIMMessage> message, zim::ZIMError errorInfo) {
            // 开发者可以通过该回调监听消息是否发送成功。
            if (errorInfo.code == zim::ZIMErrorCode::ZIM_ERROR_CODE_SUCCESS) {
                
            }
        });
    
    1
    Copied!

    接收 @ 消息

    接收 @ 消息的回调接口与接收普通消息的回调接口一致,请参考 收发普通消息 - 接收消息 了解具体接口。

    收到消息后,开发者可根据业务逻辑实现对应的功能,如高亮等。

    说明
    • 仅 2.14.0 及以上版本的 ZIM SDK 支持接收并查看 @ 信息中的内容。
    • 如果接收端的 SDK 版本介乎 [2.0.0, 2.14.0) 区间,则收到的消息和会话中不会带 @ 信息。
    • 如果接收端的 SDK 版本为 1.x.x 版本,则无法收到 @ 信息。

    获取 mentionedInfoList

    当会话内用户被提醒后,可以被动或主动获取 mentionedInfoList

    mentionedInfoList,包含 @ 消息的对应消息 ID,发送者 userID,以及 @ 消息的类型 ZIMMessageMentionedType ,开发者可用于实现标记会话等多样业务逻辑。

    被动获取

    在用户被提醒时,会收到 onConversationChanged 回调,即可获取当前 ZIMConversation 的最新 mentionedInfoList

    Untitled
    void onConversationChanged(
            ZIM * /*zim*/,
            const std::vector<ZIMConversationChangeInfo> & /*conversationChangeInfoList*/) {
        // conversationChangeInfoList 可拿到收到提醒的会话里面的 mentionInfoList 
    }
    
    1
    Copied!

    主动获取

    如用 queryConversationList 或者 queryConversation 主动拉取会话,也可获取会话里面的 mentionedInfoList ,可参考以下示例代码:

    Untitled
    std::vector<ZIMMessageMentionedInfo> mentionedInfoList = conversation.mentionedInfoList;
    
    1
    Copied!

    清除会话的 mentionedInfoList

    接收 @ 消息后,用户需要清除会话的 mentionedInfoList ,才能不再被提醒。

    清除会话的 mentionedInfoList 接口与清除会话消息未读数接口相同:

    获取被提醒用户列表

    会话内所有用户都可以调用 mentionedUserIDs 参数获取具体的被提醒用户列表。

    Untitled
    std::vector<std::string> userIds = message.mentionedUserIDs;
    
    1
    Copied!

    确认是否为全员提醒

    会话内所有用户都可以调用 isMentionAll 参数,确认消息是否为全员提醒消息。

    Untitled
    boolean isMentionAll = message.isMentionAll;
    
    1
    Copied!

    收发全员推送消息

    ZIM 支持您通过服务端向 App 所有在线用户发送消息,目标用户通过客户端接收相关消息。

    从服务端向所有用户发送消息

    请查看服务端 API 文档 全员推送 文档,实现从服务端向所有用户发送消息。

    接收服务端发送的全员推送消息

    说明
    • 仅 2.10.0 及以上版本的 ZIM SDK 支持接收并查看全员推送消息的内容。
    • 如果接收端的 SDK 版本介乎 [2.0.0, 2.10.0) 区间,不可以收到服务端发送的全员推送消息,如需获取此条消息,请将 SDK 升级为 2.10.0 或以上版本。

    通过 onBroadcastMessageReceived 回调,即可接收全员推送消息。

    示例代码:

    Untitled
    // 用户接收全员推送消息
    virtual void onBroadcastMessageReceived(ZIM * /*zim*/, const std::shared_ptr<ZIMMessage> & /*message*/) {}
    
    1
    Copied!

    转发消息

    ZIM SDK 支持实现以下两种形式的消息转发:

    • 合并消息后转发。
    • 逐条消息转发。

    具体实现流程,请参考 转发消息

    接收 Tips 消息

    ZIM SDK 支持用户在会话内的操作转换为 Tips 消息。当相关操作出现后,ZIM SDK 会向会话发送一条 Tips 消息进行通知,详情请参考 接收 Tips 消息

    监听消息状态

    在一些弱网场景中,可能存在以下场景,即消息发送成功,但由于某些因素(如网络丢包),导致 ZIM SDK 未收到服务端应答。此时,ZIM SDK 会因应答超时而认为消息发送失败,但实际上消息发送成功,导致消息状态混乱。为解决该问题,明确消息最终状态, 2.6.0 或以上版本 SDK 支持开发者监听 onMessageSentStatusChanged 回调,接收消息的状态变化。消息的状态有三种,即 Sending、Success 和 Failed。根据消息状态的变化,开发者可判断消息发送是否成功,并在业务上做相应处理。

    Untitled
    // 监听消息状态
    void onMessageSentStatusChanged(zim::ZIM *zim, const std::vector<ZIMMessageSentStatusChangeInfo> &messageSentStatusChangeInfoList{
        // 开发者可以在这里监听消息状态变更的回调。
    }
    
    1
    Copied!

    Previous

    群成员管理

    Next

    获取历史消息