服务端更新消息问题

borened 5月前 294

我们现在是做智能回复流式输出回复的场景。需要一个字一个字的更新。专业版使用MessageAdmin.updateMessageContent() sdk更新消息时,IM服务端会生成多条记录,也就是更新多少次就有有多少条记录,这样设计是否大量浪费了存储空间? 而且产生了另一个问题,查询最近记录时还需要手动去重!

最新回复 (18)
  • HeavyRain 5月前
    引用 2
    MessageAdmin.updateMessageContent()更新消息时并不会产生多条记录,是在原有消息的基础之上更新。有个问题是每次updateMessageContent所做的任务都相当于重新发送一次的资源消耗,如果是在大群中会特别消耗资源,所以如果是大群中需要控制更新的频率
  • borened 5月前
    引用 3
    我看数据库已经生成多条记录了,不然我为什么提这个问题呢?你们可以检查下你们那边代码的逻辑,我这边逻辑是一直在更新,
  • borened 5月前
    引用 4

    t_messages表生成了多条记录

  • HeavyRain 5月前
    引用 5
    我们检查一下
  • HeavyRain 5月前
    引用 6
    https://docs.wildfirechat.cn/blogs/数据库重复消息ID的问题.html 
  • borened 5月前
    引用 7
    好的,t_user_messages这张表得数据不会也重复把?
  • HeavyRain 5月前
    引用 8
    尴尬了,这个表也会有重复。我们这边研究了一下,这种流式的数据最好是用透传消息来处理,关于透传消息请参考  https://docs.wildfirechat.cn/base_knowledge/message_content.html#消息类型 。这种消息的特点只有在线用户能收到,不在线用户不会收到。处理过程如下:
    1,流式数据第一条发对应的消息,得到消息ID。
    2,后面数据使用透传消息,更新后的内容和原消息ID在消息体中,当在线用户收到这个消息后更新本地消息。
    3,流式数据的最后一条消息去调用更新接口。

    因为透传消息的代价很低,所以这种方式应该是性能最好的,建议用这种方式处理
  • HeavyRain 5月前
    引用 9
    或者是一开始只发透传消息,客户端收到透传消息不停地更新UI,然后最后再发送一条普通消息,这样处理应该更好
  • borened 5月前
    引用 10
    我觉得你们的更新消息sdk问题很大,根本不是频率的问题,sdk名叫更新消息,结果操作结果还有插入操作,导致两张表数据都重复了?这怎么都说不通把?  这还好是测试阶段就发现了问题。。。希望你们多多优化一下后端逻辑把。
  • borened 5月前
    引用 11
    HeavyRain 或者是一开始只发透传消息,客户端收到透传消息不停地更新UI,然后最后再发送一条普通消息,这样处理应该更好
    发透传消息服务器不存储了,最后去更新一次避免之前的重复问题我能理解。只是发送消息的时候能指定消息的id吗。你讲的 更新后的内容和原消息ID在消息体中  ,服务端的sdk MessagePayload对象里面没看到可以设置消息id字段啊。
  • x86 5月前
    引用 12

    @HeavyRain

    是不是应该在协议栈里面直接去支持流式消息。

    首先客户端定义几个消息:

    1. StreamStartTextMessageContent,存储并计数,是UI 层显示的具体消息
    2. StreamAppendTextMessageContent,透传,包含start消息的messageUid和本次新append的内容,协议栈收到该消息之后,更新start消息
    3. StreamEndTextMessageContent,存储不计数,包含start消息的messageUid和流式输出最终的结果,这条消息可选

    然后,server api提供几个流式输出相关的接口

    1. startStreamMessage,其实就是发送StreamStartTextMessageContent
    2. appendStreamMessage,触发发送StreamAppendTextMessageContent
    3. endStreamMessage,更新start消息,并发送StreamEndTextMessageContent

    拉取历史消息时,特殊处理StreamEndTextMessageContent消息,可以直接抛弃。

  • HeavyRain 5月前
    引用 13
    borened 发透传消息服务器不存储了,最后去更新一次避免之前的重复问题我能理解。只是发送消息的时候能指定消息的id吗。你讲的 更新后的内容和原消息ID在消息体中 ,服务端的sdk MessagePayload对 ...
    MessagePayload 需要跟客户端一起定义规则,把消息内容编码后放入MessagePayload中,可以参考其他类型的消息的编码方法
  • borened 5月前
    引用 14
    HeavyRain MessagePayload 需要跟客户端一起定义规则,把消息内容编码后放入MessagePayload中,可以参考其他类型的消息的编码方法
    意思还是需要自定义消息类型是吧,客户端要做一定的适配把。
  • HeavyRain 5月前
    引用 15
    对,因为IM服务和协议栈传递的是messagePayload,客户端需要把messagePayload转换成对应的消息内容,所以需要对齐格式
  • borened 5月前
    引用 16
    HeavyRain 对,因为IM服务和协议栈传递的是messagePayload,客户端需要把messagePayload转换成对应的消息内容,所以需要对齐格式
    这个方案看起来可行,还需要测试验证。不过按你的思路服务端步骤1(开始时发送消息)和3(结束时更新消息)都会触发消息存储逻辑。如果中间透传的速度较快,因为IMServer那边入库是异步的,理论上我感觉还是会有消息记录重复的风险啊。
  • HeavyRain 5月前
    引用 17
    HeavyRain 或者是一开始只发透传消息,客户端收到透传消息不停地更新UI,然后最后再发送一条普通消息,这样处理应该更好
    可以用这种方法,不要发开始消息,直接发送透传消息,最后发一个最终的消息。UI上需要处理好透传消息的显示问题
  • borened 5月前
    引用 18
    可以说说客户端详细具体的处理逻辑吗,现在我理解的是需要加两种消息类型。客户端如何区别透传消息和最终消息,并最终把这些消息片段显示在一条消息块中。
  • HeavyRain 5月前
    引用 19
    对的,是2种消息类型,参考文本消息和正在输入消息来定义这2个消息,定义之后就可以根据接收消息回调来收到这2个消息,然后再想办法做UI
返回