
IM即时通讯
安全可靠、全球互通

实时音视频
流畅稳定、省钱省力
回答:
从技术角度来看,消息的状态就是发送(输入消息、发送中,发送成功/失败)和接收状态(已接收)。
从产品角度来看,消息发送和接收也都容易理解容易处理,容易混淆的是“阅读状态”。
消息的“阅读状态”是针对于会话而言的(以单聊为例,下同),需要区分对话双方,A 和 B 进行聊天,A 是否已读和 B 是否已读显然是不同的问题:
1:A 和 B 分别维护自己的阅读状态,涉及处理“新消息”和“历史消息”的关系
2:让对方看自己的阅读状态 涉及“消息回执”
“阅读状态”的判定从本质上讲是一个无解的问题,用户到底读没读消息是不可判定的,举个例子:就算用户在会话界面不断翻页浏览,技术上也无法判定具体用户做了什么。目前是基于一些假设实现的,主要假设如下:
1:用户进入会话,假设用户会浏览本会话里的的未读消息;
对应的处理是会话有新消息,进入会话时通过调用 clearUnreadCount 设为自己已读
请注意,融云服务器端消息是没有状态的,具体状态是根据消息的发送时间(消息达到服务器端的时间)和用户阅读时间戳(用户已读的最后一条消息的发送时间)的关系来计算得知的,clearUnreadCount 就是在不断的更新这个时间戳,用户的阅读时间戳在浏览器做本地缓存(请注意保护相应缓存),经此处理,新消息变为历史消息,所以,从服务器端再次获取的历史消息为自己已读
2:语音消息,假设用户点击播放了就是读取了消息;
对应的处理是点击播放语音时,标为本条语音已读,数据集成时自行处理维护(如果在业务里假设用户必须播放完成才算已读,则处理时改进对应逻辑)
3:图片、文件消息等,目前默认跟随假设1,业务集成时也可以仿照假设2进行定义和处理
4:业务可以做其他的一些逻辑设定,并基于现在的数据进行处理
附相关的技术处理方式(以 Web 为例):
1:消息状态:http://support.rongcloud.cn/kb/NjE0
2:消息回执(本质是基于 lastMessage 传递 sentTime,因为消息里的时间都是服务器端时间):
var content = {
lastMessageSendTime: lastMessage.sentTime,
messageUId: lastMessage.messageUId,
type: 1
};
var conversationType = RongIMLib.ConversationType.PRIVATE;
var targetId = lastMessage.targetId;
var msg = new RongIMLib.ReadReceiptMessage(content);
RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
onSuccess: function (message) {
},
onError: function (errorCode,message) {
}
});