单群聊已读回执
IMLib SDK 从 1.3.0 版本开始支持该功能。
已读回执功能可以让消息的发送方知道消息是否被对方已读。
- 在单聊场景下,当接收方已读消息后,可以主动发送已读回执给发送方,发送方通过监听已读回执消息来获得已读通知。
- 在群聊场景下,当一条消息发送到群组后,发送方可以在消息发送完成后主动发起已读回执请求。群组中的其他成员在读到这条消息后,可以对请求进行响应。发送方通过监听已读回执响应结果来获知哪些群成员已读了这条消息。
SDK 提供了一个已读回执监听器 MessageReadReceiptListener
,用于处理单聊、群聊已读回执相关的事件通知。
单聊已读回执
单聊具体流程描述:
- 发送方通过 SDK 发送任何的记录未读的消息,比如文本、图片等。
- 接收方进入聊天页面看到最新消息。
- 接收方将当前会话最后一条消息的 sentTime 作为时间戳参数,调用 IMEngine.sendReadReceiptMessage() 接口发送单聊已读回执。
- 发送方收到单聊已读回执之后, SDK 将回执中时间戳之前的本地消息都置为已读(SentStatus 设置为 Read),然后触发 MessageReadReceiptListener.onMessageReadReceiptReceived
- 发送方在聊天页面收到 MessageReadReceiptListener.onMessageReadReceiptReceived 之后,把时间戳之前的消息 UI 都置为已读。
发送单聊已读回执
消息接收方在阅读过某条消息后,需要主动发送已读回执给发送方。调用 sendReadReceiptMessage
方法时需要传入指定消息的发送时间(message.sentTime
),或者传入会话最后一条消息的发送时间(conversation.sentTime
)。
接口原型
public sendReadReceiptMessage(conId: ConversationIdentifier, timestamp: number): Promise<IAsyncResult<void>>;
参数说明
参数名 | 类型 | 详细说明 |
---|---|---|
conId | ConversationIdentifier | 会话唯一标识对象,需包含有效的会话类型和会话 targetId |
timestamp | number | 已读时间戳(单位:毫秒),表示该时间点之前的消息已读 |
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Private;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 传入 message.sentTime 或 conversation.sentTime,此处用本地时间做示例
let time = Date.now();
IMEngine.getInstance().sendReadReceiptMessage(conId, time).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
单聊已读回执实际是一条已读通知消息,由 SDK 内部构建并发出。回调中返回的 Message
对象的 content
属性包含类型为 ReadReceiptMessage
的消息内容体对象。
接收单聊已读回执
消息的发送方需要使用 addMessageReadReceiptListener
设置已读回执监听器,才能在收到接收方发送的单聊已读回执时收到通知。SDK 收到单聊消息的已读回执后,会读取其中携带的时间戳,将本地消息数据库中该单聊会话的早于该时间戳的所有消息的 SentStatus
属性改为 READ
,同时触发 MessageReadReceiptListener
的 onMessageReadReceiptReceived
方法。
示例代码
let listener: MessageReadReceiptListener = {
onMessageReadReceiptReceived: (message: Message): void => {
// 此处为单聊消息回执回调方法,可在这做回执消息处理
},
onMessageReceiptRequest: (conId: ConversationIdentifier, messageUid: string): void => {
},
onMessageReceiptResponse: (conId: ConversationIdentifier, messageUid: string, respondUserIdList: Map<string, number>): void => {
}
}
IMEngine.getInstance().addMessageReadReceiptListener(listener);
应用程序可以从 onMessageReadReceiptReceived
方法中获取 Message
对象,并从其 content
属性中的消息内容体对象 ReadReceiptMessage
中获取其携带的时间戳。在 UI 展示本端已发送的消息时,可以将早于该时间戳的消息均展示为对方已读。
群聊已读回执
群聊已读回执功能基于消息的全局唯一 messagUId。通过在群聊会话中传递消息的 messagUId,消息发送者可获得一条指定消息的阅读进度和已读用户列表。在群聊会话中,本端发出的消息的 ReadReceiptInfo
属性中记录了该条消息的群组已读回执数据。
群聊已读回执的工作流程如下:
群聊具体流程描述 :
- 发送方发送任何的记未读消息,比如文本、图片等。
- 发送方进入聊天页面手动点击回执请求按钮,发送方调用 IMEngine.sendReadReceiptRequest() 发送群已读回执请求。
- 接收方接收到消息的已读回执请求,并更新消息的 isReadReceiptMessage 为 true,同时触发 MessageReadReceiptListener.onMessageReceiptRequest()
- 接收方进入聊天页面,查询当前页面 isReadReceiptMessage 为 true 的消息。
- 接收方过滤聊天页面内所有 (isReadReceiptMessage == true && hasRespond == false) 的消息,调用 IMEngine.sendReadReceiptResponse() 发送已读回执响应,证明接收方这些消息已读过,接收方 SDK 会将这些消息的 hasRespond 设为 true,请避免重复调用 sendReadReceiptResponse 方法。
- 发送方接收到已读回执响应时,将本地消息的 respondUserIdList 更新,然后触发 MessageReadReceiptListener.onMessageReceiptResponse() 方法。
- 发送方在对应的聊天页面,找到对应的消息,更新对应的 UI。
1. 发起群聊已读回执请求
发送者向群组中发送消息后,必须先主动发起已读回执请求,获取群成员的主动响应,才能获取该条消息的阅读状态。在一个群组会话中,只有消息发送者可以发起群聊已读回执请求。
消息发送完成后,消息发送者使用 sendReadReceiptRequest
方法,传入已发送的 Message
对象,对这条消息发起已读回执请求,SDK 内部会构建并发出一条群聊已读回执请求消息。
示例代码
// 应该使用发送成功的消息,此处进行了简写
let msg : Message;
IMEngine.getInstance().sendReadReceiptRequest(msg).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
// 成功
});
2. 接收群聊已读回执请求
群组成员均需要使用 addMessageReadReceiptListener
设置已读回执监听器,才能接收到群组内的已读回执请求。在任意群成员发起已读回执请求后,其他群成员会通过 MessageReadReceiptListener
的 onMessageReceiptRequest
回调收到已读回执请求。
示例代码
let listener: MessageReadReceiptListener = {
onMessageReadReceiptReceived: (message: Message): void => {
},
onMessageReceiptRequest: (conId: ConversationIdentifier, messageUid: string): void => {
// 收到群聊消息已读回执请求
},
onMessageReceiptResponse: (conId: ConversationIdentifier, messageUid: string, respondUserIdList: Map<string, number>): void => {
}
}
IMEngine.getInstance().addMessageReadReceiptListener(listener);
onMessageReceiptRequest
方法中会返回消息的 messageUId,您可以通过 getMessageByUid
方法获取消息对象,用于后续响应已读回执请求。
3. 接收者响应群聊已读回执请求
消息接收者使用 sendReadReceiptResponse
方法,传入会话类型、群组 ID 和 Message
对象列表,发起已读回执响应。注意会话类型一定是 ConversationType.Group
。
您可以根据用户的阅读进度,对已读回执请求进行响应。如果一次接收到多个请求,可以批量响应已读回执请求,但一次只能批量响应同一个会话中的已读回执请求
示例代码
let conId = new ConversationIdentifier();
conId.conversationType = ConversationType.Group;
conId.targetId = "TestTargetId"; // 按需填写实际的会话 id
// 需要具体的消息,此处进行了简写
let msgArray = new Array<Message>();
let msg : Message;
msgArray.push(msg);
IMEngine.getInstance().sendReadReceiptResponse(conId, msgArray).then(result => {
if (EngineError.Success !== result.code) {
// 失败
return;
}
if (!result.data) {
// 成功的消息体列表为空
return;
}
// 发送响应成功的消息列表
let msgList = result.data as List<Message>;
});