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

2024-03-27 19:26:32 +08:00
 awesomePower

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

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

3494 次点击
所在节点    程序员
20 条回复
vcn8yjOogEL
2024-03-27 20:13:59 +08:00
设备向服务端发起一个连接, 并定时发送心跳包维持这个连接
通知到达后服务器通过这个连接向设备推送, 如果设备不在线就放进缓冲区等待设备上线

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

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

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

---

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

微信在国内会自己挂一个推送服务并将 FCM 作为备用推送渠道, 国外则会直接用 FCM
vcn8yjOogEL
2024-03-27 20:16:13 +08:00
心跳包的发送频率应当根据网络环境自动调整
vcn8yjOogEL
2024-03-27 20:18:18 +08:00
主要压力在服务器后端, 能用厂商提供的设施就不要自己做
coderxy
2024-03-27 20:21:16 +08:00
本质上就是一个千万同时在线的 im 服务器而已,只不过这个场景,绝大多数 client 在大部分时间都是只保持一个心跳状态, 真的有推送了才会有信息交互。基本上用的应该都还是 tcp
bronyakaka
2024-03-27 20:51:43 +08:00
对于 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
2024-03-27 20:56:40 +08:00
websocket MQTT
gamexg
2024-03-27 21:55:16 +08:00
如前面说的,
就是设备向服务器建立一个 tcp 连接,然后这个连接基本可以看作永久不关闭, 设备或服务器定时通过这个连接发送 包,并检查是否收到回应.
如果设备发现这个连接存在问题,则重新建立一个连接替换掉原来的连接.

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

现在服务器性能是很不错的,应付大量的这种连接没什么问题.
haikea
2024-03-27 22:39:42 +08:00
服务器不可以主动请求设备吧?应该都是设备向服务器发送请求。你可以了解一下物联网常用的 MQTT
gochat
2024-03-27 23:56:30 +08:00
https://github.com/LockGit/gochat 即时通讯系统,可以了解下
gochat
2024-03-28 00:01:52 +08:00
Tabjy
2024-03-28 05:18:13 +08:00
@vcn8yjOogEL

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

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

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

dperf 的 TCP 协议栈单机可以做到几十亿并发。https://github.com/baidu/dperf
awesomePower
2024-03-29 08:31:12 +08:00
@me1onsoda
@ben666
谢谢分享

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

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

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

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

© 2021 V2EX