聊天会话列表该怎么处理

2021-03-07 08:46:48 +08:00
 awanganddong

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

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

2718 次点击
所在节点    程序员
17 条回复
xuanbg
2021-03-07 09:52:33 +08:00
通用的做法就是:不分页!你看 qq 、微信、钉钉,哪个会话列表是分页的?

你一定要分页,那就接受分页带来的问题:只能刷新当前页。
awanganddong
2021-03-07 09:54:44 +08:00
那如果不分页的话,如果会话比较多怎么处理
xuanbg
2021-03-07 10:08:49 +08:00
@awanganddong 事实上,对于会话较多的处理办法,还是分页。但这个分页不是常见的列表的那种分页,而是魔改的分页。常见的分页是从第 1 页开始,每次取 10-20 行。这种肯定是不行的了,但我们可以增加第 0 页,并定义一个较大的容量,譬如 100 行。然后自动刷新第 0 页即可。你要下拉,那就正常在 100 行之后分页加载。假设你在第 3 页找到了会话,那这个会话就会被提到最上面,你刷新第 0 页,你的会话就出现在最上面了。完美!
c9792536451
2021-03-07 10:14:20 +08:00
肯定是分页 按时间排序 最新的在最前 每次可视区域都拿一个分页里的数据
awanganddong
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
2021-03-07 10:24:07 +08:00
如果分页,肯定牵扯到数据到变化,比如我分到第三页,有一个数据叫张三。这时候,数据变化,我分到第四页,又查到了这个张三的数据。(服务端数据变化)


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

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

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

至于你说的第二个方法,确实简单一些。
awanganddong
2021-03-07 19:45:08 +08:00
刚才思考了,opengps 的方法理解了。
带上最后一页时间或者主键 id,然后查接下来的数据。
itsql
2021-03-08 14:28:01 +08:00
不分页,后台做查询优化,简化不做表关联查询,或者直接把最新的会话放 redis 的,一查就出来了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/759200

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX