Web 推送通知的内部工作原理
您会看到新消息、订单更新或付款提醒的通知。
这看起来很简单。您的后端发送一条消息,用户就会收到。
实际上,这个过程涉及许多复杂的环节。您的后端从不直接与浏览器通信,而是使用推送服务(Push Service)。
Google Chrome 使用 Firebase Cloud Messaging。Firefox 使用 Mozilla Push Service。
工作流程如下:
后端 → 推送服务 → 浏览器 → Service Worker → 用户
以下是如何使用 React 和 Golang 构建该系统。
组件构成
- 前端 (React):请求权限并注册 Service Worker。
- Service Worker:运行在浏览器中的后台脚本。即使您的网站已关闭,它也能处理事件。
- 后端 (Golang):存储订阅信息并发送加密消息。
- 推送服务:将消息传递给浏览器的中间人。
订阅流程
要发送消息,您需要一个订阅。
- 用户授予权限。
- 浏览器生成一个包含端点(endpoint)和安全密钥的订阅对象。
- 您的 React 应用将此对象发送到您的 Golang 后端。
- 您的后端将其保存到数据库中。
您必须使用 VAPID 密钥来标识您的服务器。前端使用公钥,后端使用私钥。切勿共享您的私钥。
实现方式
在 React 中,您注册一个 Service Worker 来监听推送事件。该 Worker 在后台运行,接收数据并向用户显示通知。
在 Golang 中,您使用库来处理加密和 VAPID 身份验证。您的服务器从数据库中读取订阅信息,加密有效载荷(payload),然后将其发送到浏览器推送服务。
生产环境的扩展
简单的设置适用于小型项目,而大型系统则需要更多考虑。
- 处理多设备:一个用户可能同时拥有手机和笔记本电脑。请为每个用户存储多个订阅。
- 清理数据:订阅会过期。如果您收到 404 或 410 错误,请从数据库中删除该订阅。
- 使用队列:对于数百万用户,请使用 Kafka 或类似的工具。这允许您的系统异步处理通知。
- 实现重试机制:使用指数退避(exponential backoff)来处理网络故障。
当用户处于活跃状态时,WebSockets 非常适合实时聊天;而当标签页关闭时,Web Push 更适合触达用户。
