圈组消息收发
更新时间: 2024/11/21 17:18:38
NIM SDK 的QChatMessageService
接口提供圈组消息收发的方法,支持支持文本、图片、语音、视频、文件、地理位置和自定义等消息类型。定义圈组消息的结构体为QchatMessage
。
消息类型
消息类型 |
API关键字 |
说明 |
---|---|---|
文本消息 | text |
消息内容为普通文本 |
图片消息 | image |
消息内容为图片 URL 地址、尺寸、图片大小等信息 |
语音消息 | audio |
消息内容为语音文件的 URL 地址、时长、大小、格式等信息 |
视频消息 | video |
消息内容为视频文件的 URL 地址、时长、大小、格式等信息 |
文件消息 | file |
消息内容为文件的 URL 地址、大小、格式等信息 |
位置消息 | location |
消息内容为地理位置标题、经度、纬度信息 |
提示消息 | tip |
又叫做 Tip 消息,没有推送和通知栏提醒,主要用于会话内的通知提醒,例如进入会话时出现的欢迎消息,或是会话过程中命中敏感词后的提示消息等场景 |
通知消息 | notification |
主要用于圈组的事件通知 |
自定义消息 | custom |
开发者自定义的消息类型,例如红包消息、石头剪子布等形式的消息 |
技术原理
下图展示了集成并初始化 NIM SDK 后,实现圈组消息收发的基本工作流。图中的 QChat 即为 NIM SDK 的圈组组件,云信服务端包含 IM 服务端和圈组服务端。
- 上图仅以静态 Token 登录为例展示消息收发流程。网易云信 IM 还支持动态 Token 登录鉴权和第三方回调登录鉴权,相关详情请参见登录鉴权。
- 圈组服务端与圈组服务器是两个不同概念,前者指云信服务器内提供圈组功能的服务端,后者为圈组的特殊概念,对应 Discord 的 Server, 为社群本身。
上图中的流程可归纳为如下 5 步:
- 账号集成与登录。
- 开发者将应用的用户账号传入云信 IM 服务端,注册云信 IM 账号。
- 云信 IM 服务端返回 Token 给应用服务端。
- 应用客户端登录应用服务端。
- 应用服务端将 Token 返回给应用客户端。
- 用户A 和用户B 带 Token 登录云信 IM 服务端。
- 用户A 和用户B 登录云信圈组服务端,此时无需再传入 Token 等参数。
- 用户A 创建圈组服务器,并在服务器内创建频道。
- 用户B 加入圈组服务器。
- 用户A 在频道发送一条消息到云信圈组服务端。
- 云信圈组服务端投递消息至频道,用户B 接收消息。
前提条件
- 已开通圈组功能。
- 已完成圈组初始化。
如果用户所在服务器的成员人数超过 2000 人阈值,该用户还需先订阅相应的服务器或频道,才能收到对应服务器或频道的消息。如未超过该阈值,则无需订阅。订阅相关说明,请参见圈组订阅机制。
实现流程
实现消息收发
API 调用时序
sequenceDiagram
note over NIM SDK: 初始化SDK并登录IM
note over NIM SDK: 注册监听并登录圈组
发送方 ->> NIM SDK: 监听消息状态变化事件<br>(onMessageStatusChange)
发送方 ->> NIM SDK: 监听消息附件上传/下载进度回调<br>(onAttachmentProgress)
note left of 发送方: 仅多媒体消息收发需要
发送方 ->> NIM SDK: 登录圈组
接收方 ->> NIM SDK: 监听消息接收事件<br>(onReceiveMessage)
接收方 ->> NIM SDK: 登录圈组
note over NIM SDK: 双方都成为同一服务器的成员
note over NIM SDK: 双方都能访问同一频道
note over NIM SDK: 发送方拥有在该频道发送消息的权限
note over NIM SDK: 消息收发
发送方 ->> NIM SDK: 在频道发送消息<br>(sendMessage)
NIM SDK ->> 接收方: 投递消息(QChatMessage)
接收方 ->> NIM SDK: 将消息标记为已读<br>(markMessageRead)
接收方 ->> NIM SDK: 下载附件<br>(downloadAttachment)
note left of 发送方: 可选,仅多媒体消息收发需要
NIM SDK ->> 接收方: 下载进度
NIM SDK ->> 接收方: 下载状态
流程说明
本节仅对上图中标为部分的流程进行说明,其他流程请参考相关文档。例如:
- 服务器成员相关说明,可参见圈组服务器成员管理
- 权限相关说明,可参见身份组相关文档。
-
发送方在登录圈组前,注册
onMessageStatusChange
消息状态变化事件回调,监听圈组消息状态和消息附件传输状态的变化。如果发送的是多媒体消息(包括图片、语音、视频和文件消息),还需注册
onAttachmentProgress
消息附件上传/下载进度回调。
示例代码如下:
注册消息状态变化回调NimCore.instance.qChatObserver.onMessageStatusChange.listen((event) { //todo message status change });
注册消息附件上传/下载进度回调NimCore.instance.qChatObserver.onAttachmentProgress.listen((event) { //todo message attach process });
-
接收方在登录圈组前,注册
onReceiveMessage
消息接收事件回调。示例代码如下:
NimCore.instance.qChatObserver.onReceiveMessage.listen((event) { //todo show message });
-
发送方调用
sendMessage
方法发送消息,调用时通过消息类型参数type
设置消息的类型。调用时必须传入必须传入serverId
、channelId
和type
。消息发送方需要拥有发送消息的权限(sendMsg)。
QChatSendMessageParam
类为该方法的入参结构,包含设置内容审核、消息抄送、第三方回调、推送等的参数,其中部分重要参数说明如下:参数类型 说明 antiSpamOption
QChatMessageAntiSpamOption
安全通(易盾反垃圾)相关的各项参数。如果您配置了这些参数,在发送消息时,会对发送的文本和附件进行内容审核(反垃圾检测)。根据您在控制台预设的拦截/过滤规则,如果检测到违规内容,消息可能发送失败或者敏感信息被过滤。 圈组的安全通功能属于增值功能,需要在开通圈组功能后再额外开通。如尚未开通,请通过云信官网首页提供的联系方式咨询商务经理开通。更多相关说明请参见圈组内容审核。 mentionedAccidList
List<String>
@某个人,如果将该消息设置为@所有人或者@身份组,则本参数无效) 用户需要拥有@某个人权限( remindOther
)才能@某个人。mentionedAll
bool 是否@所有人 用户需要拥有@所有人的权限( remindEveryone
)才能@某个人。mentionedRoleIdList
List<int>
@身份组 historyEnable
bool 消息是否存储云端历史 needBadge
bool 是否需要消息计数 发送各类型消息的示例代码如下:
文本//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramText = QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.text); paramText.body = '文本消息'; NimCore.instance.qChatMessageService .sendMessage(paramText) .then((value) { if (value.isSuccess) { //todo success } else {} });
图片//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramImage = QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.image); paramImage.setAttachment(NIMImageAttachment(size: size, path: 'filePath')); NimCore.instance.qChatMessageService .sendMessage(paramImage) .then((value) { if (value.isSuccess) { //todo success } else {} });
语音//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramAudio = QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.audio); paramAudio.setAttachment(NIMAudioAttachment(size: size, path: 'filePath')); NimCore.instance.qChatMessageService .sendMessage(paramAudio) .then((value) { if (value.isSuccess) { //todo success } else {} });
视频//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramVideo = QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.video); paramVideo.setAttachment(NIMVideoAttachment(size: size, path: 'filePath')); NimCore.instance.qChatMessageService .sendMessage(paramVideo) .then((value) { if (value.isSuccess) { //todo success } else {} });
文件//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramFile = QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.file); paramFile.setAttachment(NIMFileAttachment(size: size, path: 'filePath')); NimCore.instance.qChatMessageService .sendMessage(paramFile) .then((value) { if (value.isSuccess) { //todo success } else {} });
提示//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramTip= QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.tip); paramTip.body = "提示消息"; NimCore.instance.qChatMessageService .sendMessage(paramTip) .then((value) { if (value.isSuccess) { //todo success } else {} });
自定义//channelId 为之前创建好的Channel 的Id //serverId 为之前创建好的Server 的Id var paramCustom= QChatSendMessageParam( channelId: channelId, serverId: serverId, type: NIMMessageType.custom); NimCore.instance.qChatMessageService .sendMessage(paramCustom) .then((value) { if (value.isSuccess) { //todo success } else {} });
-
消息接收回调触发,接收方通过该回调收到消息。
-
接收方调用
markMessageRead
方法将接收到的消息标记为已读。- 将消息标记为已读后,该消息之前接收到的消息全部变为已读状态。
- 如果传入的时间戳参数为 0,则频道内所有消息将被标记为未读。
- 该方法调用存在频控,300ms 内最多可调用一次。
示例代码如下:
var paramRead = QChatMarkMessageReadParam( serverId: serverId, channelId: channelId, ackTimestamp: ackTimestamp); NimCore.instance.qChatMessageService .markMessageRead(paramRead) .then((value) { if (value.isSuccess) { //todo success } else {} });
-
如果接收方接收到的是多媒体消息,可调用
downloadAttachment
方法下载附件。下载附件会触发
QChatobserver
的onAttachmentProgress
回调通知下载进度,同时触发observeMessageStatusChange
通知下载状态。默认情况下(即 SDK 初始化时将
NIMSDKOPtions#enablePreloadAttachment
设置为true
,开启预加载多媒体消息附件),当 SDK 收到多媒体消息后,如果附件是图片或视频,会自动下载图片或视频的缩略图;如果附件是音频,SDK 会自动下载音频文件。如果需要下载原图或者原视频等,可调用该方法下载附件。
示例代码如下:
var paramDownAttach = QChatDownloadAttachmentParam(message: message, thumb: true) NimCore.instance.qChatMessageService.downloadAttachment(paramDownAttach).then((value){ if (value.isSuccess) { //todo success } else {} });
实现消息重发
如果因为网络等原因消息发送失败,可以调用resendMessage
方法重发消息。该方法的入参QChatResendMessageParam
需传入待重发的消息体(QChatMessage
)。
示例代码如下:
var paramResendMessage = QChatResendMessageParam(message);
NimCore.instance.qChatMessageService.resendMessage(paramResendMessage).then((value){
if (value.isSuccess) {
//todo success
} else {}
});
相关参考
相关控制台配置
-
每个频道上的 消息未读数 (包括@消息的未读数)默认最多显示为 99+ 。
最大未读数可在云信控制台配置
在云信控制台选择应用,进入IM 即时通讯 > 功能配置 > 圈组 > 子功能配置 > 所有未读消息(包括@)的消息计数即可配置。
-
@消息的未读数的有效期,默认为 7 天。
可在云信控制台配置该有效期
在云信控制台选择应用,进入IM 即时通讯 > 功能配置 > 圈组 > 子功能配置 > 未读的@消息数-周期即可配置。