V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
awesomePower
V2EX  ?  程序员

求教,推送的本质是什么?服务器如何向几百万台手机设备推送的信息的

  •  
  •   awesomePower · 30 天前 · 2597 次点击

    腾讯云最新优惠活动来了:云产品限时1折,云服务器低至88元/年 ,点击这里立即抢购:9i0i.cn/qcloud,更有2860元代金券免费领取,付款直接抵现金用,点击这里立即领取:9i0i.cn/qcloudquan

    (福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

    如题。是设备不断向服务器发送 tcp 或者 udp 请求吗?还是服务器记录了设备的网络地址,反向向设备请求。

    有了解类似技术细节的大佬告知下吗

    20 条回复  ?  2024-03-29 08:31:12 +08:00
    vcn8yjOogEL
        1
    vcn8yjOogEL  
       30 天前   ?? 6
    设备向服务端发起一个连接, 并定时发送心跳包维持这个连接
    通知到达后服务器通过这个连接向设备推送, 如果设备不在线就放进缓冲区等待设备上线

    一般操作系统会提供一个统一的服务处理所有通知, 例如 Android 的谷歌 FCM 和 iOS 的苹果 APNS

    FCM 在国内可以直连, 但没有优化线路所以效果一般, 没有其他谷歌服务使用也麻烦, 所以国产都做了自己的推送服务, 但也因此出现了碎片化, App 需要给不同厂商单独接入

    APNS 要求 App 把推送信息交给苹果, 苹果直接把通知推到手机, FCM 则支持让推送唤醒 App, App 去获取实际内容并生成通知; 前者更省电, 但功能有限, 例如 Signal 这种端到端加密聊天因为服务端无法解密而无法通过 APNS 推送消息内容

    ---

    客户端轮询也可以, 但想消除延迟就需要快速唤醒所以很耗电, 一般不建议使用

    微信在国内会自己挂一个推送服务并将 FCM 作为备用推送渠道, 国外则会直接用 FCM
    vcn8yjOogEL
        2
    vcn8yjOogEL  
       30 天前
    心跳包的发送频率应当根据网络环境自动调整
    vcn8yjOogEL
        3
    vcn8yjOogEL  
       30 天前
    主要压力在服务器后端, 能用厂商提供的设施就不要自己做
    coderxy
        4
    coderxy  
       30 天前   ?? 1
    本质上就是一个千万同时在线的 im 服务器而已,只不过这个场景,绝大多数 client 在大部分时间都是只保持一个心跳状态, 真的有推送了才会有信息交互。基本上用的应该都还是 tcp
    bronyakaka
        5
    bronyakaka  
       30 天前   ?? 2
    对于 iOS 设备:

    使用 Apple Push Notification Service (APNs):每个 iOS 应用在注册推送通知后会获得一个唯一的 Device Token 。服务器端将要推送的消息、目标设备的 Device Token 以及其它必要参数封装成推送请求,发送给 Apple 的 APNs 服务器。
    APNs 与每台 iPhone 、iPad 等设备维持一个持久连接(长连接)。
    当服务器端发送推送消息时,通过与 APNs 的连接将消息转发至对应的设备。
    设备收到推送消息后,即使应用不在前台运行,也能显示通知并将消息存储,用户点击通知时可以唤醒对应的应用。
    对于 Android 设备:

    Google Firebase Cloud Messaging (FCM) 或其他第三方推送服务:类似 iOS ,Android 设备也会通过相应的服务获取一个 Registration ID ,并将其发送给服务器。
    服务器通过与 FCM 服务器接口交互,将消息和目标设备的 Registration ID 一起发送给 FCM 。
    FCM 利用自身的长连接网络服务将消息分发到各个设备。
    设备接收到消息后,根据消息类型显示通知,或者静默处理。
    zed1018
        6
    zed1018  
       30 天前
    websocket MQTT
    gamexg
        7
    gamexg  
       30 天前   ?? 1
    如前面说的,
    就是设备向服务器建立一个 tcp 连接,然后这个连接基本可以看作永久不关闭, 设备或服务器定时通过这个连接发送 包,并检查是否收到回应.
    如果设备发现这个连接存在问题,则重新建立一个连接替换掉原来的连接.

    如果服务器需要通知设备,则直接通过这个连接向设备发送数据即可.

    现在服务器性能是很不错的,应付大量的这种连接没什么问题.
    haikea
        8
    haikea  
       30 天前
    服务器不可以主动请求设备吧?应该都是设备向服务器发送请求。你可以了解一下物联网常用的 MQTT
    gochat
        9
    gochat  
       30 天前   ?? 2
    https://github.com/LockGit/gochat 即时通讯系统,可以了解下
    gochat
        10
    gochat  
       30 天前
    Tabjy
        11
    Tabjy  
       30 天前
    @vcn8yjOogEL

    > 前者更省电, 但功能有限, 例如 Signal 这种端到端加密聊天因为服务端无法解密而无法通过 APNS 推送消息内容

    不是 ios 开发者,但是好像有个 notification service app extension [0] 可以被系统调用主动并处理通知

    [0] https://developer.apple.com/documentation/usernotifications/modifying-content-in-newly-delivered-notifications
    opengps
        12
    opengps  
       30 天前   ?? 1
    前几楼说的足够详细了,我简略说几句:
    1 ,如果是应用自己的连接,那么需要程序运行,有一个公用的 socket 服务(通常是 tcp ),作为客户端,主动连接服务端,登陆后先发送自己的 id ,所以服务器可以随时下发信息。最典型的应用是所有的实时位置服务类应用,比如打车软件。
    2 ,如果应用自己没做连接,则需要借助手机系统自身的推送来实现,手机厂商维护了一个公共的连接,可以转发,因此可以做到 app 没运行都被系统通知,然后通过点击来“叫醒”app
    awesomePower
        13
    awesomePower  
    OP
       30 天前
    awesomePower
        14
    awesomePower  
    OP
       30 天前
    服务器保持这么多 TCP 连接,会不会压力很大
    qinfengge
        15
    qinfengge  
       30 天前
    看下极光 push ,国内每家安卓厂商都有自己的推送渠道,可以在不打开 APP 的情况下离线推送,但是需要每家厂商都配一遍,恶心死了。之前说的统一推送联盟直接没下文?
    opengps
        16
    opengps  
       30 天前   ?? 1
    @awesomePower 只要处理得当,低配单机承载个几万很轻松,甚至十多万也可以(但由于维护困难,比如重启一下程序需要十几分钟才能完成所有连接的重新建立,所以会用多台低端机的方案)
    me1onsoda
        17
    me1onsoda  
       30 天前
    tcp 长连接,server 可以随时写到 channel ,而不是不断的请求
    awesomePower
        18
    awesomePower  
    OP
       30 天前
    @opengps 谢谢解答
    ben666
        19
    ben666  
       30 天前
    对于这种单一的业务,完全可以用 DPDK 实现用户态协议栈,单机支持几百万连接问题不大。
    对于很多特定场景的业务,很多大厂都在协议栈上下了很多功夫。

    dperf 的 TCP 协议栈单机可以做到几十亿并发。https://github.com/baidu/dperf
    awesomePower
        20
    awesomePower  
    OP
       29 天前
    @me1onsoda
    @ben666
    谢谢分享
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3019 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 08:20 · PVG 16:20 · LAX 01:20 · JFK 04:20
    Developed with CodeLauncher
    ? Do have faith in what you're doing.


    http://www.vxiaotou.com