V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
awanganddong
V2EX  ›  程序员

聊天会话列表该怎么处理

  •  
  •   awanganddong · 2021-03-07 08:46:48 +08:00 · 2709 次点击
    这是一个创建于 1139 天前的主题,其中的信息可能已经有所发展或是发生改变。

    即时通讯聊天会话列表 需要对该列表做下拉分页 但是在下拉分页过程中又存在返回数据顺序的变化, 即按最后回复时间对会话排序

    像这一块,通用做法是什么

    17 条回复    2021-03-08 14:28:01 +08:00
    xuanbg
        1
    xuanbg  
       2021-03-07 09:52:33 +08:00
    通用的做法就是:不分页!你看 qq 、微信、钉钉,哪个会话列表是分页的?

    你一定要分页,那就接受分页带来的问题:只能刷新当前页。
    awanganddong
        2
    awanganddong  
    OP
       2021-03-07 09:54:44 +08:00
    那如果不分页的话,如果会话比较多怎么处理
    xuanbg
        3
    xuanbg  
       2021-03-07 10:08:49 +08:00
    @awanganddong 事实上,对于会话较多的处理办法,还是分页。但这个分页不是常见的列表的那种分页,而是魔改的分页。常见的分页是从第 1 页开始,每次取 10-20 行。这种肯定是不行的了,但我们可以增加第 0 页,并定义一个较大的容量,譬如 100 行。然后自动刷新第 0 页即可。你要下拉,那就正常在 100 行之后分页加载。假设你在第 3 页找到了会话,那这个会话就会被提到最上面,你刷新第 0 页,你的会话就出现在最上面了。完美!
    c9792536451
        4
    c9792536451  
       2021-03-07 10:14:20 +08:00 via iPhone
    肯定是分页 按时间排序 最新的在最前 每次可视区域都拿一个分页里的数据
    awanganddong
        5
    awanganddong  
    OP
       2021-03-07 10:18:41 +08:00
    @xuanbg 你这个魔改的分页,假设你在第三页找到会话。。。 从这里开始我就不明白什么意思了。
    下边是微信 sdk 的说明

    ```
    由于本地会话可能很多(例如超过 500 个),一次性全部加载完毕可能会耗时很久,导致界面展示比较慢。为了提升用户体验,getConversationList() 接口支持分页拉取能力:

    首次调用 getConversationList() 接口时,可以指定其参数 nextSeq 为 0,表示从头开始拉取会话列表,并指定 count 为 50, 表示一次拉取 50 个会话对象。
    IM SDK 按照从新到旧的顺序拉取会话列表,当首次拉取会话列表成功后,getConversationList() 的回调结果 V2TIMConversationResult 中会包含下次分页拉取的 nextSeq 字段以及会话拉取是否完成的 isFinish 字段:
    如果 isFinished 返回 true,表示所有会话已经拉取完成。
    如果 isFinished 返回 false,表示还有更多的会话可以拉取。此时并不意味着要立刻开始拉取“下一页”的会话列表。在常见的通信软件中,分页拉取通常由用户的滑动操作触发的,用户每下拉一次会话列表就触发一次分页拉取。
    当用户继续下拉会话列表时,如果还有没有拉取下来的会话列表,可以继续调用 getConversationList 接口,并传入新一轮的 nextSeq 和 count 参数(数值来自上一次拉取返回的 V2TIMConversationResult 对象)。
    重复执行 步骤 3 直至 isFinished 返回 true 。

    ```
    awanganddong
        6
    awanganddong  
    OP
       2021-03-07 10:24:07 +08:00
    如果分页,肯定牵扯到数据到变化,比如我分到第三页,有一个数据叫张三。这时候,数据变化,我分到第四页,又查到了这个张三的数据。(服务端数据变化)


    那如果维持一个 list 列表,每次拉取数据,放 list 列表处理,这个容量限制呢?
    opengps
        7
    opengps  
       2021-03-07 12:44:24 +08:00
    我做过,分页还是存在的,但不是常规的排序后的取第几页,而是用时间段去拉取全部值,比如每次拉取 100 条,没次都用上一次的截止时间作为开始时间
    opengps
        8
    opengps  
       2021-03-07 12:46:51 +08:00
    一种方法:每次拉取指定间隔,不限制单页总数量,由于空返回和超量返回,所以不太提倡
    另一种做法,就是上一句我说的,每次限制最大返回行数,每次请求用上一次的截至时间,并且服务器端来维护指定已经拉取的最后一条消息的时间

    另外有个,需要特别注意,客户端需要做好标记,防止重复拉取等问题,对于信息框的显示,只显示没有显示过的 id 的信息
    opengps
        9
    opengps  
       2021-03-07 12:48:09 +08:00
    以上两种方法仅仅针对短链接,对于长连接,则可能是服务器端主动推送,这时候跟分页可能关联不大,但也可能是用推送触发分页拉取的方案
    helloxiaofan
        10
    helloxiaofan  
       2021-03-07 14:13:16 +08:00
    每条消息应该有 messageId 吧,用 messageId 排序?
    awanganddong
        11
    awanganddong  
    OP
       2021-03-07 15:28:43 +08:00 via Android
    我这里想拉取的列表是比如现在有几个聊天好友的列表。而不是聊天消息。
    xuanbg
        12
    xuanbg  
       2021-03-07 17:20:58 +08:00
    @awanganddong 微信这个就是我说的分页啊,你下拉 3 次加载了第三页,找到了张三,然后你点击张三进入会话,那么张三这个会话是不是就应该提上去到第 0 页的第一条。所以刷新第 0 页,张三就会出现在会话列表的最上面。当然,在第三页你应该把张三的会话删除掉。
    xuanbg
        13
    xuanbg  
       2021-03-07 17:22:08 +08:00
    @xuanbg 是上拉不是下拉……
    xuanbg
        14
    xuanbg  
       2021-03-07 17:26:07 +08:00
    还有个更简单的更新会话列表的方法,就是会话状态发生变化的时候,直接丢弃整个列表数据重新加载第 0 页就好了,至于第 0 页后面的数据,自己去上拉更新。
    awanganddong
        15
    awanganddong  
    OP
       2021-03-07 19:33:40 +08:00 via Android
    @xuanbg 点击会话,触发请求。更改会话顺序,直接请求第一页,正好把张三放在第一页。

    那如果,我不点击会话,一直上拉,中途新加入几个会话,这又乱序了。

    至于你说的第二个方法,确实简单一些。
    awanganddong
        16
    awanganddong  
    OP
       2021-03-07 19:45:08 +08:00 via Android
    刚才思考了,opengps 的方法理解了。
    带上最后一页时间或者主键 id,然后查接下来的数据。
    itsql
        17
    itsql  
       2021-03-08 14:28:01 +08:00
    不分页,后台做查询优化,简化不做表关联查询,或者直接把最新的会话放 redis 的,一查就出来了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   909 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:02 · PVG 05:02 · LAX 14:02 · JFK 17:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.