默认

IM开发干货分享:我是如何解决大量离线消息导致客户端卡顿的

查看数: 258971 | 评论数: 33 | 收藏 8
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2020-06-15 15:50

正文摘要:

1、引言 好久没写技术文章了,今天这篇不是原理性文章,而是为大家分享一下由笔者主导开发实施的IM即时通讯聊天系统,针对大量离线消息(包括消息漫游)导致的用户体验问题的升级改造全过程。 文章中,我将从如 ...

评论

椎锋陷陈 发表于 2 年前
引用:在每次下拉加载离线消息时,将收到的上一批离线消息的msgId或消息偏移量等信息发送给服务端,服务端直接根据msgId删除离线库中已经发送给客户端的离线消息,再返回给客户端下一批离线消息。


这里的意思应该是拉取下一批离线消息时传入msgId或消息偏移量等信息,本身就可以充当ACK的作用,不需要额外再使用和在线消息处理一样的ACK逻辑吧。
小张 发表于 2 年前
引用:JackJiang 发表于 2021-10-10 17:47
我在这个帖子里回复你了:http://www.52im.net/thread-3698-1-1.html

OKk
JackJiang 发表于 2 年前
引用:小张 发表于 2021-10-09 21:08
我这边设计,基本都是文章中的一个套路(非一次性全量拉取,采用推拉方式)。但是,这些设计方式,对于单个 ...

我在这个帖子里回复你了:http://www.52im.net/thread-3698-1-1.html
小张 发表于 2 年前
我这边设计,基本都是文章中的一个套路(非一次性全量拉取,采用推拉方式)。但是,这些设计方式,对于单个会话消息记录很多,感觉总会有瓶颈,比如A群,2天聊了2w条数据,1周聊了5w条数据,客户端进行缺失消息同步时,服务端的数据库查询就需要扫描N万条记录,再取出M条,会查询的很慢慢慢。
有什么好方式解决吗?
张文-im 发表于 3 年前
引用:手写的从前 发表于 2020-12-31 14:44
我的意思是怎么判断一个消息应该不应该被拉取到客户端呢? 有一个拉取到的最新消息id吗?

可以采用严格递增id,当客户端发现id出现跳跃时,重新从跳跃前的那个id拉取消息,可能会拉取到重复消息,所以需要客户端做去重处理。当然,严格递增id很难保证,redis的incr应该可以
手写的从前 发表于 3 年前
引用:JackJiang 发表于 2020-12-31 13:58
尽量在客户端做去重容错,服务端为了防止露拉,可以把重复这个容忍度设计的高一点

我的意思是怎么判断一个消息应该不应该被拉取到客户端呢? 有一个拉取到的最新消息id吗?
JackJiang 发表于 3 年前
引用:手写的从前 发表于 2020-12-31 12:55
那会不会因为某些原因导致在一个群里比如我已经拉去到消息id为100,但是又在存储中插入了一个id为99的消 ...

尽量在客户端做去重容错,服务端为了防止露拉,可以把重复这个容忍度设计的高一点
手写的从前 发表于 3 年前
引用:JackJiang 发表于 2020-12-31 11:42
是这个意思。

那会不会因为某些原因导致在一个群里比如我已经拉去到消息id为100,但是又在存储中插入了一个id为99的消息,导致这条消息就丢失了?
JackJiang 发表于 3 年前
引用:手写的从前 发表于 2020-12-31 11:16
这里的推是指推送《有新消息通知》,而拉指的是拉去消息本身吗?

是这个意思。
手写的从前 发表于 3 年前
引用:JackJiang 发表于 2020-08-06 12:33
1、不要用推,还是要用拉简单,这是主流作法。
2、文中的意思是拉未读数的时候就取首屏。

这里的推是指推送《有新消息通知》,而拉指的是拉去消息本身吗?
boboking1 发表于 3 年前
引用:JackJiang 发表于 2020-12-25 21:22
这么大量消息的情况下,最好是服务端推通知,客户端B收到通知后再分页拉取合理一点

谢谢大佬的解答
JackJiang 发表于 3 年前
引用:boboking1 发表于 2020-12-25 18:05
大佬,插个额外话题。客户端接受方B在线的时候,服务端发送海量数据(假设几万条)给B。现在有2个疑问
1 ...

这么大量消息的情况下,最好是服务端推通知,客户端B收到通知后再分页拉取合理一点
boboking1 发表于 3 年前
引用:JackJiang 发表于 2020-11-03 13:55
他这个逻辑里,应该是会请求一次服务端,然后拉下所有离线消息,后绪直到退出app前,都以本地数据为准

大佬,插个额外话题。客户端接受方B在线的时候,服务端发送海量数据(假设几万条)给B。现在有2个疑问
1、这种在线高并发情况下,是采用B定时去服务器去拉好,还是服务端即时推比较好。
2、是否不论推或者拉,也都是采用获取部分数据而不是全量数据呢?
JackJiang 发表于 3 年前
引用:GarageBand 发表于 2020-11-03 14:03
意思是在群A中,比如有1000条未读消息,客户端下拉一次把1000数据一次性全部拉取存入本地数据库,后面下 ...

是的,这样技术上不用太复杂
GarageBand 发表于 3 年前
引用:JackJiang 发表于 2020-11-03 13:55
他这个逻辑里,应该是会请求一次服务端,然后拉下所有离线消息,后绪直到退出app前,都以本地数据为准

意思是在群A中,比如有1000条未读消息,客户端下拉一次把1000数据一次性全部拉取存入本地数据库,后面下拉就走客户端数据库本地缓存?
JackJiang 发表于 3 年前
引用:GarageBand 发表于 2020-11-03 13:50
比如有100条未读消息,我只看了20条(拉取20条),这个时候客户端数据库中的消息就会“断层”,然后我重 ...

他这个逻辑里,应该是会请求一次服务端,然后拉下所有离线消息,后绪直到退出app前,都以本地数据为准
GarageBand 发表于 3 年前
引用:JackJiang 发表于 2020-11-03 13:43
"如果客户端没拉完所有的离线消息,那么客户端会一直走请求":
这句怎么理解?用专业一点的话组织一下呢

比如有100条未读消息,我只看了20条(拉取20条),这个时候客户端数据库中的消息就会“断层”,然后我重新进入聊天会话中,这个时候客户端上拉,是走请求?还是走客户端本地数据库?
整体意思就是,客户端不知道啥时候去请求服务器拉取历史消息?还是走本地数据库获取数据?依据是啥?
JackJiang 发表于 3 年前
引用:GarageBand 发表于 2020-11-03 13:39
按图中所3,4条所述,如果客户端没拉完所有的离线消息,那么客户端会一直走请求,当再次进入会话中,客户端 ...

"如果客户端没拉完所有的离线消息,那么客户端会一直走请求":
这句怎么理解?用专业一点的话组织一下呢
GarageBand 发表于 3 年前
按图中所3,4条所述,如果客户端没拉完所有的离线消息,那么客户端会一直走请求,当再次进入会话中,客户端还是一样会走请求,即便客户端已经缓存过拉取过的历史离线消息,是这样吗?

返回顶部