角色=>前端:web、小程序、客户端(ios、安卓);服务端;腾讯IM;
1、背景
IM消息ID不一致,本地没有缓存历史数据,导致在调用腾讯sdk方法时,id不一致报错问题
2、调研目的
- 消息ID不统一的原因
- 腾讯IM消息ID规则
- 找到唯一ID的方法
3、问题描述
因为腾讯返回给服务端的MsgKey和前端的msgID不一样,没有唯一标识。
场景是拉我们自己服务端的历史记录接口。
如果 客户端 发了一条信息到 小程序,这个时候 小程序 是腾讯IM返回的msgID
客户端 退出了应用,又重新进入应用。
进入会话页-我们会重新拉取服务端的历史记录接口。这个时候客户端只有腾讯给服务端的MsgKey字段,并不是msgID。
那现在 客户端 想要撤回刚刚的消息,需要调用腾讯的SDK,在消息体里面需要一个消息ID,这个消息ID需要msgID的(也就是腾讯返回给前端的ID),但是现在客户端调取接口只有一个MsgKey,所以发生错误
4、腾讯IM消息ID规则 cloud.tencent.com
- 客户端单聊/群聊消息 msg_id 的组成是:
tinyid-clientTime-random
- Web 端单聊/群聊消息 msgID 的组成是(v2.18.0及以上):
tinyid-clientTime-random
- 服务端单聊消息 msgKey 的组成是:
clientSeq_random_serverTime
5、消息ID不统一的原因
我理解就是他们客服自己也不明白为啥不一样
6、消息ID不一样的表现
小程序实时接收到的格式:
"message": {
"ID": "144115244425849730-1715418597-12766512",
"conversationID": "C2Cdl5qrip454w0",
"conversationType": "C2C",
"time": 1715418597,
"sequence": 1657570002,
"clientSequence": 1657570002,
"random": 12766512,
"from": "djrfbu1gq51c",
"to": "dl5qrip454w0",
"flow": "out",
"isSystemMessage": false,
"protocol": "JSON",
"isResend": false,
"isRead": true,
"status": "success",
"clientTime": 1715418597,
"senderTinyID": "144115244425849730",
"revokerInfo": {
"userID": "",
"nick": "",
"avatar": ""
},
"type": "TIMCustomElem"
}
客户端实时接收到的格式:
服务端实时接收到的格式:
[
Data:{
"msgType": 7,
"groupCode": "1789217509812125696",
"fromAccount": "1783382717849858048",
"targetAccount": "1788444782364856320",
"msgTriggerType": 2,
"groupType": 0,
"msgDigest": "看看看看看看看",
"content": {text:"看看看看看看看 "},
"visibleRoles": "0011",
"status": "unSend",
"consultationOrderCode": "PO1789217509556285440",
"isMe": true
},
MsgRandom:"12766512",
MsgSeq:"1657570002",
MsgTime:"1715418597",
MsgKey:"1657570002_12766512_1715418597",
OnlineOnlyFlag:"0"
]
历史记录接口返回的格式
{
groupCode: "1793578864715370496",
msgContent: "{"keywords":[{"keyword":"{ConnectCustomer}","link":"400-888-6890","linkType":2,"replaceKeyword":"联系客服"}],"text":"医生将在 12 小时内与您沟通,逾期未回复,您可继续等待或 {ConnectCustomer}"}"
msgKey: "1657570002_12766512_1715418597",
msgRetraction: false,
msgSeq: 1657570002,
msgTime: 1715418597,
MsgRandom: 12766512, // 需要接口新增当前字段
msgType: 6,
senderCode: "1792395382068744192",
}
7、通过对比发现
前端 可以通过 历史记录接口 中的 msgTime、MsgRandom和当前用户的tinyID拼接成前端的msg_id
小程序可以在登录的成功回调中获取到当前用户的tinyID。客户端的登录成功回调没有返回参数
所以说前端和服务端id不同,只缺一个tinyID就可以手动拼接
8、腾讯IM的反馈
这个tinyID是腾讯根据用户的userid
生成的。
tinyid
是后台给userid
的映射,但是userid并不是tinyid
如果你需要判断一个消息是否为同一个,可以通过severtime和random判断
客户端可以通过xlog日志获取到tinyID https://cloud.tencent.com/developer/article/1502366
9、解决方案
1、前端获取tinyID
- 客户端在登录的时候,读取IM的日志文件,获取到当前用户的 tinyID ,拿到tinyID后保存到服务器
- 进入对话页,先根据群code获取当前会话页人员的 tinyID 接口——新增接口
- 根据senderCode和ownerCode判断是不是自己发送的消息
- 如果是患者,使用患者的tinyID拼接,医生 使用医生的tinyID拼接
2、通过后端获取tinyID
- 进入对话页调用后台的一个接口,以当前群组内的医生和患者名义自动触发一个消息,当前消息不上屏。
- 前端拿到当前的实时消息后,分别存储医生和患者的tinyID
- 调用服务端历史记录接口遍历判断是否为自己发送,拼接ID
3、拉取腾讯的历史记录接口
- 需要区分最近拉取的20条数据,是否是当前群组的,如不是,继续拉取
- 安卓可以设置拉取某个时间段内的记录,web&小程序不可以
4、等待腾讯SDK更新