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


相关推荐
花花鱼16 分钟前
vue3 axios ant-design-vue cdn的方式使用
前端·javascript·vue.js
GoppViper1 小时前
uniapp中实现<text>文本内容点击可复制或拨打电话
前端·后端·前端框架·uni-app·前端开发
Sam90291 小时前
【Webpack--007】处理其他资源--视频音频
前端·webpack·音视频
Code成立1 小时前
HTML5精粹练习第1章博客
前端·html·博客·html5
架构师ZYL1 小时前
node.js+Koa框架+MySQL实现注册登录
前端·javascript·数据库·mysql·node.js
一只小白菜~2 小时前
实现实时Web应用,使用AJAX轮询、WebSocket、还是SSE呢??
前端·javascript·websocket·sse·ajax轮询
晓翔仔3 小时前
CORS漏洞及其防御措施:保护Web应用免受攻击
前端·网络安全·渗透测试·cors·漏洞修复·应用安全
GISer_Jing4 小时前
【前后端】大文件切片上传
前端·spring boot
csdn_aspnet4 小时前
npm 安装 与 切换 淘宝镜像
前端·npm·node.js
GHUIJS4 小时前
【Echarts】vue3打开echarts的正确方式
前端·vue.js·echarts·数据可视化