V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
movq
V2EX  ›  前端开发

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

  •  
  •   movq · 2022-02-03 15:51:48 +08:00 · 3285 次点击
    这是一个创建于 812 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我的想法是这样的:

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

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

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

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

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

    12 条回复    2022-02-04 14:28:00 +08:00
    Chad0000
        1
    Chad0000  
       2022-02-03 18:47:49 +08:00   ❤️ 1
    如果让我做,那么:

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

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

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

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

    如果仅仅是 PC 上应用,个人感觉轮询和 websocket 都差不多,两者没啥太大区别。
    zqx
        11
    zqx  
       2022-02-04 11:15:26 +08:00 via Android
    业界常见做法就是前端轮询,后端直接从 mysql 分页查,没有消息队列,也不需要推送。
    movq
        12
    movq  
    OP
       2022-02-04 14:28:00 +08:00
    @chendy 是我发的,场景就是 web 论坛里面私信提醒之类的,感觉也不需要多大的实时性
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3336 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:10 · PVG 20:10 · LAX 05:10 · JFK 08:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.