前端新消息提示,这样实现的思路是对的吗?

2022-02-03 15:51:48 +08:00
 movq

我的想法是这样的:

如果有给这个用户的新消息,先把具体内容存到数据库,然后把有新消息的通知进入 rabbitmq 队列

如果此时用户在线,直接发送到前端(只是通知前端消息数目+1 ,不发送具体消息内容)

如果用户不在线,就先放在队列里面。用户前端上线后,和后端建立 websocket 连接,然后后端就把队列里面积累的东西发过去

用户点击消息提示之后,再从后端查询数据库,得到所有的新消息的具体内容

这样做有什么问题吗?业界通常的做法是什么?

3446 次点击
所在节点    前端开发
12 条回复
Chad0000
2022-02-03 18:47:49 +08:00
如果让我做,那么:

新消息来后直接入 RabbitMQ ,防止消息太多数据库压力大。Consumer 负责将数据入库,同时判断用户是否在线,在线就发给用户,不在线就标记最新版本号。

用户上线后先通过 API 获取最新版本号,如果有未读消息则同时获取消息内容。之后再建立连接开始接收新消息。
Chad0000
2022-02-03 18:59:39 +08:00
但如果是给后台用,而且用户量不大,能接受若干秒延迟,则可以直接使用 HTTP 而不是 Websocket ,每隔一段时间比如 30 秒请求一次即可。是否有最新消息这个标记保存在 Redis 中。

我的后台应用就是这么弄的,配合 Long Polling 实在秒提醒。
liuzhedash
2022-02-03 21:03:52 +08:00
早年论坛实现都是轮询,数据库压力没有那么夸张。
当然,这个只适合站内信的场景,不适合高频率的 IM 对话那种。
LeeReamond
2022-02-03 21:23:08 +08:00
@Chad0000 轮训和 ws 的开销怎么说,30s 轮训一次开销比 ws 高多少?
chendy
2022-02-03 22:24:53 +08:00
隔壁 sf 的这个帖子是楼主发的么 https://segmentfault.com/q/1010000041363597
这问题不知道具体业务场景不好说啊
seki
2022-02-03 23:43:09 +08:00
kaneg
2022-02-04 00:08:15 +08:00
如果有用户一直不上线,消息就一直存在 mq 里?如果有大量类似场景,mq 就会由大量消息堆积而挂掉
jinliming2
2022-02-04 00:44:50 +08:00
你的消息队列里存的是消息通知,而不是消息内容??
用到消息队列,应该是缓解数据库那边的压力吧?如果你的消息可以直接入数据库,那应该没必要用消息队列了?新消息来了先写数据库,然后判断用户是否在线,在线的话就推一条新消息通知,用户阅读的时候再查数据库获取数据。
如果消息量比较大的话,就先把消息放到消息队列,消息入队的时候不通知用户,队列直接输出对接到数据库入库。写完数据库再判断用户是否在线,在线推送。

至于轮询和 websocket 的选择,看具体的业务实时性:1 、实时性要求非常低,那么完全可以不推送,用户刷新的时候获取新消息( V2EX 貌似就是这个模式),2 、web app ,用户很少会刷新页面,而实时性要求不高的话,用轮询 30 秒、1 分钟,3 、要求实时性高的场景,则使用 websocket ,几乎是实时的。
轮询需要接口能够承受住刷新请求,websocket 需要服务端能够持有足够多的 socket 连接。
至于 #6 的 push 消息,使用场景不太一样,主要用于用户没有访问你的网站时也可以收到通知推送(类似于手机 APP 的后台被杀掉,也还是可以通过 FCM/APNs 收到实时推送消息)。你需要注册一个 service worker ,然后用户不需要打开你的网站也可以收到消息推送(只要浏览器在运行,sw 就能在后台接收消息推送),消息推送的形式是通过浏览器的 notification 弹窗(用户必须先授权弹窗)。
Chad0000
2022-02-04 01:58:45 +08:00
@LeeReamond #4 ws 主要是开发变得复杂以及服务器能承载的 ws 数量有限(只看过相关文章没有测试过)
3dwelcome
2022-02-04 04:52:48 +08:00
websocket 在安卓上有很大的坑,因为设计上是多线程的。有时候 webview 生命周期结束了,websocket 还挂在后台。

如果仅仅是 PC 上应用,个人感觉轮询和 websocket 都差不多,两者没啥太大区别。
zqx
2022-02-04 11:15:26 +08:00
业界常见做法就是前端轮询,后端直接从 mysql 分页查,没有消息队列,也不需要推送。
movq
2022-02-04 14:28:00 +08:00
@chendy 是我发的,场景就是 web 论坛里面私信提醒之类的,感觉也不需要多大的实时性

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

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

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

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

© 2021 V2EX