现在有个 IM 功能,一个好友下线了,如何让他的好友收到这个通知?(如果服务器挂掉呢?) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
lsk569937453
V2EX    程序员

现在有个 IM 功能,一个好友下线了,如何让他的好友收到这个通知?(如果服务器挂掉呢?)

  •  
  •   lsk569937453 2022-04-11 16:14:14 +08:00 2382 次点击
    这是一个创建于 1277 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景:类似 QQ 聊天,前后端用 websocket 通信(发聊天记录,更新状态)。 问题: 1.如果两个好友 A 和 B 都用手机在线聊天,如果其中一个好友 A 下线了,另外一个好友 B 怎么更新他的好友状态(更新为离线)?如果 A 连接的服务器挂掉了,A 的好友们(手机端)如何更新 A 的状态? 2.两个好友发消息。A 发了:"你好"。B 是怎么获取消息的?服务器推消息到 B 吗?还是 B 主动去拉消息?如果是服务器推消息,A 连接的服务器和 B 连接的服务器不是一台服务器,怎么通知?

    11 条回复    2022-04-11 17:12:35 +08:00
    raycool
        1
    raycool  
       2022-04-11 16:18:57 +08:00
    1. A 下线通知了服务器,服务器告诉 B ,A 下线了,你更新下状态吧。
    2. A 发了你好,服务器接受到了消息,服务器发现是要告诉 B 的,直接推送给 B 。
    macrorules
        2
    macrorules  
       2022-04-11 16:21:52 +08:00
    B 主动去拉比较好,这样就不用占用服务器太多资源
    如果是服务器推消息:
    A -> [A Server]
    A Server 查看目标 B ,看看本地有没有这个连接,如果没有,发送到"路由器"
    路由器广播:谁有 B 的连接啊...
    B Server: B is at 10.11.11.12
    最后 A Server 拿到 B 的所在服务器,记录在缓存里(有 TTL ),下次再找 B , 直接查表
    GBdG6clg2Jy17ua5
        3
    GBdG6clg2Jy17ua5  
       2022-04-11 16:27:38 +08:00
    1.离线状态信息可以推拉结合。A 下线的时候,给好友推个信息。B 也可以隔段时间更新下在线列表。
    2.A 、B 不在同一个服务器,你们总是用同一个数据库,或者通过订阅 mq 获取消息吧?
    0o0O0o0O0o
        4
    0o0O0o0O0o  
       2022-04-11 16:33:39 +08:00 via iPhone
    我觉得在线状态是靠心跳包和主动发消息来维护的,一段时间没有动静就是离线了,当然也要提供一个主动离线的接口。然后某个用户状态变为离线也当作一条消息来推送给别的用户。
    twing37
        5
    twing37  
       2022-04-11 16:46:11 +08:00
    1. A-> state service -> B (服务拆分)
    2. A -> MQ -> B 消息队列广播 另外一种: A-> Route GRPC -> B 私信
    涉及的东西有点多.甚至都不知道在哪开始聊
    lsk569937453
        6
    lsk569937453  
    OP
       2022-04-11 16:49:14 +08:00
    @raycool
    1. 用户 A 连接的 A 服务器,用户 B 连接的 B 服务器。此时 掉线了,A 服务器怎么通知 B 服务器?
    liuxingdeyu
        7
    liuxingdeyu  
       2022-04-11 16:49:50 +08:00
    一般是心跳维护在线状态,离线了之后给个异步任务,能找到链接 fd 的就直接发,找不到的就找个最近登录的设备发个离线推送(这里要明确推送方式,国内一般兼容 oppo vivo 华为 小米 苹果五个,国外一般税 google 和苹果)。如果挂了,你要看怎么挂,看服务是怎么布的,才能明确解决方案。由于是异步任务,大家面向 broker ,所以几个服务器也无所谓。离线状态的推送本质上来说和你的聊天消息的推送没啥区别,也就是消息定义不一样
    lsk569937453
        8
    lsk569937453  
    OP
       2022-04-11 16:53:57 +08:00
    @macrorules 你的意思是前端每 5 秒定时向后端发送 http 请求拉消息吗?就是说如果 B 有 10000 个好友和 100 个组,B 每 5 秒钟会拉所有好友的消息+好友状态+群消息+群成员状态?
    lsk569937453
        9
    lsk569937453  
    OP
       2022-04-11 16:56:19 +08:00
    @liuxingdeyu A 用 webscoket 连接的是 A 服务器,B 用 webscoket 连接的是 B 服务器,此时 A 掉线了,A 服务器怎么通知到 B 用户?
    liuxingdeyu
        10
    liuxingdeyu  
       2022-04-11 17:06:08 +08:00
    @lsk569937453 用啥连无所谓,但是你连接这块最好就只负责收发,消息处理啥的最好不要和连接耦合起来
    luman
        11
    luman  
       2022-04-11 17:12:35 +08:00
    有个点没看明白。服务器 A 和服务器 B 不是组集群么?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5597 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms TC 06:37 PVG 14:37 LAX 23:37 JFK 02:37
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86