关于腾讯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更新


相关推荐
Mintopia1 分钟前
计算机架构演进:适应不断变化的计算需求
前端
之歆5 分钟前
Day01_HTML 基础知识完全指南:从零开始的 Web 开发之旅
前端·html
IT_陈寒5 分钟前
React状态管理这个坑,我终于爬出来了
前端·人工智能·后端
深海鱼在掘金10 分钟前
Next.js从入门到实战保姆级教程(第二章):环境配置与项目初始化
前端·typescript·next.js
深海鱼在掘金12 分钟前
Next.js从入门到实战保姆级教程(第三章):项目结构与文件系统约定
前端·typescript·next.js
水木流年追梦17 分钟前
CodeTop Top 300 热门题目3-字符串相加
java·前端·算法
编码七号17 分钟前
使用playwright做前端项目的端对端自动化测试
前端·功能测试·自动化
禅思院19 分钟前
中篇:构建弹性的异步组件
前端·架构·前端框架
恋猫de小郭24 分钟前
为什么 Github Copilot 要收集你数据,也是 AI 订阅以前便宜的原因
前端·人工智能·ai编程
我叫唧唧波25 分钟前
【自动化部署】CI/CD 实战(三):让 Argo CD 接管 CD,Jenkins 镜像自动同步到集群
运维·前端·ci/cd·docker·自动化·jenkins·argocd