收发消息
功能简介
本文档适用于开发以下平台的应用:iOS、Android、macOS、Windows、Web。
ZIM SDK 支持单聊消息、群组消息、房间消息等的收发,以及查询历史消息、删除消息等功能。可广泛应用于娱乐社交、电商购物、在线教育、互动直播等多种场景下。
本文档介绍了如何使用 ZIM SDK 的接口,实现各类消息的收发功能与监听消息的状态。
消息类型
目前 ZIM 支持的消息类型如下:
消息类型 | 说明 | 特性及适用场景 |
---|---|---|
ZIMTextMessage(1) | 文本消息。消息大小不超过 32 KB,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般适用于“单聊”、“群聊”等即时聊天的场景和“房间聊天”的公屏聊天场景。房间解散后,“房间聊天”的消息不存储。 相关接口:sendMessage |
ZIMCommandMessage(2) | 开发者可自定义数据内容的信令消息。消息大小不超过 5 KB,单个客户端发送频率限制为 10 次/秒。 | 支持更高的并发;一般适用于“语聊房”、“在线课堂”等房间内的信令传输,比如上下麦操作、送礼物,发送在线课堂课件等。 相关接口:sendMessage |
ZIMBarrageMessage(20) | 房间内弹幕文本消息。消息大小不超过 5 KB,单个客户端发送频率无限制。 | 专门用于房间内的高频、不可靠、允许丢掉的消息,一般适用于发送“弹幕消息”的场景中。 支持高并发,但不可靠,不保证消息送达。 相关接口:sendMessage |
ZIMImageMessage(11) | 图片消息。支持主流图片格式,包括 JPG、PNG、BMP、TIFF、GIF、WebP,大小不超过 10 MB,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般用于单聊、房间、群聊等即时聊天场景。 相关接口:sendMediaMessage |
ZIMFileMessage(12) | 文件消息。消息内容为文件,格式不限,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。 | |
ZIMAudioMessage(13) | 语音消息。支持 MP3、M4A 格式的语音文件,时长不超过 300 秒,大小不超过 6 MB,单个客户端发送频率限制为 10 次/秒。 | |
ZIMVideoMessage(14) | 视频消息。支持 MP4、MOV 格式的视频文件,大小不超过 100 MB,单个客户端发送频率限制为 10 次/秒。仅支持视频编码格式为 H264 和 H265 的视频文件在消息发送成功后获取该视频首帧的宽、高信息。 | |
ZIMCombineMessage(100) | 合并消息,消息大小无限制,单个客户端发送频率限制为 10 次/秒。 | 消息可靠有序,可存储为历史消息(保存时间请参考 计费说明 - 版本说明 中“历史消息存储天数”。);一般用于单聊、房间、群聊等即时聊天场景。 相关接口:sendMessage |
ZIMCustomMessage(200) | 自定义消息。开发者可自定义消息的类型,并自行完成消息的解析,ZIM SDK 不负责定义和解析自定义消息的具体内容。 | 一般可用于发送投票类型、接龙类型、视频卡片类型等消息。 相关接口:sendMessage |
收发普通消息
普通消息,包含 ZIMTextMessage、ZIMBarrageMessage 等消息类型。
- 开发者可以通过实现 ZIMEventHandler 的 Function,来接收相关通知(接收房间消息、连接状态、token 即将过期等通知)。
- 接收消息时,收到的消息类型是基类 ZIMMessage。开发者需要根据其中的
type
(具体请参考 ZIMMessageType)字段,判断消息类型是 Text 还是 Command,然后强转基类为具体的子类(ZIMTextMessage 或 ZIMCommandMessage),然后从 “message” 字段获取消息内容。 - 接收消息时,可以使用消息的 orderkey 来实现排序;即 orderkey 越大,消息的时间越新。接收到消息后,会自动更新消息未读数量。
发送消息
以客户端 A 向客户端 B 发送消息为例:
- 客户端 A、B 分别创建自己的 ZIM 实例,并实现 ZIMEventHandler 中的 onReceivePeerMessage 回调方法,用于接收单聊消息通知。
- 客户端 A、B 分别登录 ZIM SDK。
- 客户端 A 调用 sendMessage 接口,设置
converversationType
为ZIMConversationType.peer
发送一条单聊消息到客户端 B。 - 客户端 B 将通过 onReceivePeerMessage 回调接口,收到客户端 A 的消息。
目前 ZIM 不支持调用 sendMessage
接口,向自己发送消息(即 toConversationID = 自己的 ID)。如果尝试向自己发送消息,会返回错误 6000001,并提示传入参数错误。
发送消息后,可以通过 ZIMMessageSentResult 类型的异步返回值,获取发送消息的操作结果。
// 1、创建 ZIM 对象,传入 AppID
ZIMAppConfig appConfig = ZIMAppConfig();
appConfig.appID = appID;
appConfig.appSign = appSign;
ZIM.create(appConfig);
// 2、登录
await ZIM
.getInstance()
!.login(userInfo, "token")
.then((value) {
//登录成功触发此处
})
.catchError((onError) {
switch (onError.runtimeType) {
// 登录失败触发此处
case PlatformException:
log(onError.code); //登录失败错误码
log(onError.message!);//登录失败错误信息
break;
default:
}
});
// 3、发送信息
ZIMTextMessage textMessage = ZIMTextMessage(message: "message");
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
// 设置消息优先级
sendConfig.priority = ZIMMessagePriority.low;
ZIMPushConfig pushConfig = ZIMPushConfig();
pushConfig.title = "离线推送的标题";
pushConfig.content = "离线推送的内容";
pushConfig.extendedData = "离线推送的扩展信息";
sendConfig.pushConfig = pushConfig;
ZIMMessageSendNotification notification = ZIMMessageSendNotification(onMessageAttached: (message){
// 发送前的回调,客户可以在这里获取一个临时对象,该对象与开发者创建的 zimMessage 对象属于同一对象,开发者可利用此特性做一些业务逻辑,如提前展示 UI 等
});
// 4、设置会话类型,选择其一向对应的会话类型发送消息
// 发送单聊信息
ZIMConversationType type = ZIMConversationType.peer;
// 发送群聊信息
ZIMConversationType type = ZIMConversationType.room;
// 发送房间信息
ZIMConversationType type = ZIMConversationType.group;
ZIM.getInstance()!.sendMessage(textMessage, toConversationID, type, sendConfig).then((value) => {
// 开发者可以通过该回调监听消息是否发送成功。
}).catchError((onError){
// 开发者可以捕获发送失败的异常。
});
接收消息
- 发送消息时,统一使用 sendMessage 接口,并根据消息类型传入对应的 ZIMConversationType 取值。
- 接收消息时:
- 单聊消息(Peer 类型),通过 onReceivePeerMessage 回调接收。
- 房间消息(Room 类型),通过 onReceiveRoomMessage 回调接收。
- 群组消息(Group 类型),通过 onReceiveGroupMessage 回调接收。
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
//收到单聊消息触发此处
};
ZIMEventHandler.onReceiveGroupMessage = (zim, messageList, fromGroupID) {
//收到群聊消息触发此处
};
ZIMEventHandler.onReceiveRoomMessage = (zim, messageList, fromGroupID) {
//收到房间消息触发此处
};
收发富媒体消息
ZIM SDK 支持发送多种类型的富媒体消息,包含图片、文件、音频、视频等消息类型,开发者可以通过以下步骤实现富媒体文件消息的收发。
- 用户登录成功后,指定消息类型(图片、文件、音频、视频)、会话类型(单聊、房间、群组)等,向指定会话发送富媒体消息。
- 接收方用户登录成功后,根据会话类型(单聊、房间、群组)的相关回调监听,接收富媒体消息的相关通知,以及下载富媒体消息文件到本地。
发送富媒体消息
用户登录成功后,调用 sendMediaMessage 接口,指定会话、消息类型(图片、文件、音频、视频)、会话类型(单聊、房间、群组)、以及相关消息配置,向指定会话发送富媒体消息。
- 发送富媒体消息时,填写的待发送文件路径,必须使用
UTF-8
编码格式。 - 如果需要向房间/群组内发送富媒体消息,消息发送者必须要在这个房间/群组内。
发送富媒体消息后,可以通过 ZIMMessageSentResult 类型的异步返回值,获取发送富媒体消息的操作结果。
富媒体文件消息的发送进度回调
开发者可以通过 ZIMMediaUploadingProgress 类型的异步返回值,接收富媒体消息的上传发送进度的相关通知。
typedef ZIMMediaUploadingProgress = void Function(
ZIMMessage message, int currentFileSize, int totalFileSize);
其中:
-
message:正在发送消息的内容。
-
currentFileSize:当前已被发送的消息大小。
-
totalFileSize:发送消息的总体大小。
接收富媒体消息
接收方用户登录成功后,根据会话类型(单聊、房间、群组)的相关回调监听(onReceivePeerMessage、onReceiveRoomMessage、onReceiveGroupMessage),接收富媒体消息的相关通知,然后可以调用 downloadMediaFile 接口,下载富媒体消息文件到本地。
下载富媒体消息时,需要指定对应的媒体消息的文件类型。
- 图片消息:可以选择下载原始文件、大图、缩略图。
- 文件/音频消息:仅能选择下载文件/音频的原始文件。
- 视频消息:可以选择下载视频原始文件、视频首帧的缩略图。
开发者可以通过 ZIMMediaDownloadedResult 类型的异步返回值,接收富媒体消息的下载进度的相关通知。
// 接收多媒体消息示例 - 单聊 接收图片消息
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
//收到单聊消息触发此处
for (ZIMMessage message in messageList) {
// 收到消息时,可通过消息的 Type 进行判断接收到何种类型的消息
switch (message.type) {
case ZIMMessageType.image:
message as ZIMImageMessage;
break;
case ZIMMessageType.video:
message as ZIMVideoMessage;
break;
case ZIMMessageType.audio:
message as ZIMAudioMessage;
break;
case ZIMMessageType.File:
message as ZIMFileMessage;
break;
default:
}
}
};
富媒体文件消息的下载进度回调
开发者可以通过 ZIMMediaDownloadingProgress 类型的异步返回值,接收富媒体消息的下载进度的相关通知。
typedef ZIMMediaDownloadingProgress = void Function(
ZIMMessage message, int currentFileSize, int totalFileSize);
其中:
- message:正在下载的消息内容。
- currentFileSize:当前已被下载的消息大小。
- totalFileSize:下载消息的总体大小。
收发信令消息
ZIM SDK 支持开发者实现信令类型的消息收发,开发者可以通过 ZIMCommandMessage 对象定义自己的消息类型,例如位置消息等。
信令消息不支持离线推送和本地存储。
以下以向指定用户发送信令消息为例。
发送信令消息
//向指定用户发送信令消息
Uint8List cmdMessage = Uint8List.fromList([1, 2, 3]);
ZIMCommandMessage commandMessage = ZIMCommandMessage(message: cmdMessage);
ZIMMessageSendConfig sendConfig = ZIMMessageSendConfig();
ZIM.getInstance()!.sendMessage(cmdMsg, 'toUserID', ZIMConversationType.peer, sendConfig)
.then((value) => {
//成功触发此处
})
.catchError((onError) {
//失败触发此处
});
接收信令消息
//用户接收信令消息
ZIMEventHandler.onReceivePeerMessage = (zim, messageList, fromUserID) {
//收到单聊消息触发此处
for (ZIMMessage message in messageList) {
switch (message.type) {
case ZIMMessageType.command:
message as ZIMCommandMessage;
break;
default:
}
}
};
收发自定义消息
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 对象定义自定义类型消息,包括以下参数:
以下为用户在单聊会话中发送自定义消息的示例代码:
// 在单聊会话中向指定用户发送自定义消息
// 1、创建 ZIM 对象,传入 appID、appSign
// 具体代码请参考上文 [收发普通消息 - 发送消息] 相关代码。
// 2、设置 setEventHandler 回调
// 具体代码请参考上文 [收发普通消息 - 发送消息] 相关代码。
// 3、登录
// 具体代码请参考上文 [收发普通消息 - 发送消息] 相关代码。
// 4、发送自定义信息
// 指定用户的 ID
String userID = "xxxx";
// 自定义消息的文本内容
String message = "";
// 具体的自定义类型
int subType = 100;
// 自定义消息的检索字段。
String searchedContent = "";
ZIMCustomMessage zimCustomMessage = ZIMCustomMessage(message, subType);
// 发送消息的高级属性配置
ZIMMessageSendConfig config = ZIMMessageSendConfig();
// 设置消息优先级
config.priority = ZIMMessagePriority.low;
// 发送单聊信息
ZIMConversationType type = ZIMConversationType.Peer;
// 发送群聊信息
// ZIMConversationType type = ZIMConversationType.Gourp;
// 发送房间信息
// ZIMConversationType type = ZIMConversationType.Room;
ZIM.getInstance().sendMessage(zimCustomMessage, toConversationID, type, config,ZIMMessageSendNotification(onMessageAttached: (ZIMMessage message){
// 开发者可以通过该回调,监听消息是否开始准备发送。只有当通过本地基础参数检验的消息才会抛出该回调,否则通过 onMessageSent 回调抛出错误。
})).then((value) {
// 发送成功回调
}).catchError((onError){
// 处理失败
});
接收自定义消息
接收自定义消息的回调接口与接收普通消息的回调接口一致,请参考 收发普通消息 - 接收消息 了解具体接口。
以下为用户在单聊会话中接收自定义消息的示例代码:
// 用户在单聊会话中接收自定义消息
ZIMEventHandler.onReceivePeerMessage = (
ZIM zim, List<ZIMMessage> messageList, String fromUserID){
for (ZIMMessage message in messageList){
if(message is ZIMCustomMessage){
}
}
};
收发 @ 消息
@ 消息,是指包含“@ + 用户”内容的消息。被 @ 的用户在收到消息时会强提醒。
@ 消息不属于消息类型。一条消息既可以是文本消息或其他类型消息,同时也是 @ 消息。
发送 @ 消息
在调用 sendMessage 发送消息时,可以通过以下 ZIMMessage 参数(可同时使用)将一条消息设置为 @ 信息:
- mentionedUserIDs:提醒指定用户(可以是会话外用户)查看消息。传入的 userID 列表长度最多为 50,如需上调,请联系 ZEGO 技术支持。
- isMentionAll:提醒会话内所有其他用户查看消息。
仅 2.14.0 及以上版本的 ZIM SDK 支持发送消息中带 @ 信息。
// 以下为用户在单聊会话中发送 @ 消息的示例代码:
try {
// 群内成员查询群组的成员列表
List<String> memtionList = ['userID1,userID2'];
// message 可以为任何类型消息
// 调用接口提醒列表中用户查看消息
message.mentionedUserIDs(memtionList);
// 提醒会话内所有其他用户查看消息
bool isMentionAll = true;
message.isMentionAll(isMentionAll);
ZIMMessageSendConfig config = ZIMMessageSendConfig();
//设置消息优先级
config.priority = ZIMMessagePriority.low;
// 是否强推送给被提醒用户(不管对方是否开启了会话免打扰),默认为 false;
config.isNotifyMentionedUsers = true;
// 以发送单聊消息为例子
ZIMConversationType type = ZIMConversationType.peer;
ZIMMessageSentResult result = await ZIM.getInstance()!.sendMessage(message, 'conv_id', type, config);
} on PlatformException catch (onError){
onError.code;//根据错误码表处理
onError.message;//错误信息
}
接收 @ 消息
接收 @ 消息的回调接口与接收普通消息的回调接口一致,请参考 收发普通消息 - 接收消息 了解具体接口。
收到消息后,开发者可根据业务逻辑实现对应的功能,如高亮等。
- 仅 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。
ZIMEventHandler.onConversationChanged = (ZIM zim, List<ZIMConversationChangeInfo> conversationChangeInfoList){
};
主动获取
如用 queryConversationList 或者 queryConversation 主动拉取会话,也可获取会话里面的mentionedInfoList,可参考以下示例代码:
List<ZIMMessageMentionedInfo> mentionedInfoList = conversation.mentionedInfoList;
清除会话的 mentionedInfoList
接收 @ 消息后,用户需要清除会话的 mentionedInfoList,才能不再被提醒。
清除会话的 mentionedInfoList 接口与清除会话消息未读数接口相同:
- clearConversationUnreadMessageCount:清除单个会话消息未读数,调用示例请参考 会话管理 - 清除单个会话消息未读数。
- clearConversationTotalUnreadMessageCount:清除全部会话消息未读数,调用示例请参考 会话管理 - 清除全部会话消息未读数。
获取提醒用户列表
会话内所有用户都可以通过 mentionedUserIDs 参数,获取具体提醒用户列表,此参数仅在返回中可以获取 mentionedUserIDs 接口传入的用户列表。
List<String> userIds = message.mentionedUserIDs;
确认是否为全员提醒
会话内所有用户都可以通过 isMentionAll 参数,确认消息是否为全员提醒消息。
bool isMentionAll = message.isMentionAll;
收发全员推送消息
ZIM 支持您通过服务端向 App 所有在线用户发送消息,目标用户通过客户端接收相关消息。
从服务端向所有用户发送消息
请查看服务单 API 文档 全员推送 文档,实现从服务端向所有用户发送消息。
接收服务端发送的全员推送消息
- 仅 2.10.0 及以上版本的 ZIM SDK 支持接收并查看全员推送消息的内容。
- 如果接收端的 SDK 版本介乎 [2.0.0, 2.10.0) 区间,不可以收到服务端发送的全员推送消息,如需获取此条消息,请将 SDK 升级为 2.10.0 或以上版本。
通过 onBroadcastMessageReceived 回调,即可接收全员推送消息。
示例代码:
// 用户接收全员推送消息
ZIMEventHandler.onBroadcastMessageReceived(zim, message){}
转发消息
ZIM SDK 支持实现以下两种形式的消息转发:
- 合并消息后转发。
- 逐条消息转发。
具体实现流程,请参考 转发消息。
接收 Tips 消息
ZIM SDK 支持用户在会话内的操作转换为 Tips 消息。当相关操作出现后,ZIM SDK 会向会话发送一条 Tips 消息进行通知,详情请参考 接收 Tips 消息。
监听消息状态
在一些弱网场景中,可能存在以下场景,即消息发送成功,但由于某些因素(如网络丢包),导致 ZIM SDK 未收到服务端应答。此时,ZIM SDK 会因应答超时而认为消息发送失败,但实际上消息发送成功,导致消息状态混乱。为解决该问题,明确消息最终状态, 2.6.0 或以上版本 SDK 支持开发者监听 onMessageSentStatusChanged 回调,接收消息的状态变化。消息的状态有三种,即 Sending、Success 和 Failed。根据消息状态的变化,开发者可判断消息发送是否成功,并在业务上做相应处理。
//监听消息状态
ZIMEventHandler.onMessageSentStatusChanged = (
ZIM zim, List<ZIMMessageSentStatusChangeInfo> messageSentStatusChangedInfoList){
for(ZIMMessageSentStatusChangeInfo info in messageSentStatusChangedInfoList){
log(info.status.toString());
log(info.message!.messageID.toString());
}
};