关于腾讯IM消息ID不统一的问题?服务端的MsgKey和前端的msgID不一样

角色=>前端: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不一样的表现

小程序实时接收到的格式:
javascript 复制代码
"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"
}
客户端实时接收到的格式:
服务端实时接收到的格式:
javascript 复制代码
[
    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"
]
历史记录接口返回的格式
javascript 复制代码
{
    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
  1. 客户端在登录的时候,读取IM的日志文件,获取到当前用户的 tinyID ,拿到tinyID后保存到服务器
  2. 进入对话页,先根据群code获取当前会话页人员的 tinyID 接口------新增接口
  3. 根据senderCode和ownerCode判断是不是自己发送的消息
  4. 如果是患者,使用患者的tinyID拼接,医生 使用医生的tinyID拼接
2、通过后端获取tinyID
  1. 进入对话页调用后台的一个接口,以当前群组内的医生和患者名义自动触发一个消息,当前消息不上屏。
  2. 前端拿到当前的实时消息后,分别存储医生和患者的tinyID
  3. 调用服务端历史记录接口遍历判断是否为自己发送,拼接ID
3、拉取腾讯的历史记录接口
  1. 需要区分最近拉取的20条数据,是否是当前群组的,如不是,继续拉取
  2. 安卓可以设置拉取某个时间段内的记录,web&小程序不可以
4、等待腾讯SDK更新


相关推荐
DCTANT16 分钟前
【原创】vue-element-admin-plus完成确认密码功能,并实时获取Form中表单字段中的值
前端·javascript·vue.js·elementui·typescript
汪子熙23 分钟前
使用 Trae 开发一个演示勾股定理的动画演示
前端·人工智能·trae
GISer_Jing1 小时前
字符串操作&栈和队列
前端·javascript
黑土豆1 小时前
TypeScript技术系列13:深入理解配置文件tsconfig.json
前端·javascript·typescript
zheshiyangyang1 小时前
JavaScript---原型和原型链
开发语言·前端·javascript
momo_养身版2 小时前
Browser use — 利用 AI 操作浏览器 · 原理篇
前端·openai
悲且狂2 小时前
Vue环境搭建:vue+idea
前端·vue.js·intellij-idea
Allen Bright2 小时前
【XML基础-1】深入理解XML:介绍、语法规则与实际应用
xml·前端
大个个个个个儿2 小时前
vue3腾讯云直播 前端拉流(前端页面展示直播)
前端·javascript·腾讯云
momo_养身版2 小时前
Browser use — 利用 AI 操作浏览器 · 实践篇
前端·ai编程