角色=>前端: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更新