Mercure 是一种高效的实时消息推送协议和工具集,专注于解决在现代 Web 应用中实时通信的需求。
与 WebSocket 相比,Mercure 更轻量且更易集成,尤其适合基于事件流的场景。
核心特点包括:
- 简单易用:支持标准的 Server-Sent Events (SSE),浏览器内置支持,无需额外的客户端库。
- 灵活性:支持细粒度的订阅控制和基于 JWT 的授权机制,可满足复杂场景需求。
- 开源:官方实现 Mercure Hub 提供了可靠的参考,同时还有许多第三方实现。
Mercure 是一个开源协议和工具集,旨在实现高效的实时通信,特别适合需要服务器主动向客户端推送更新的场景。相比于 WebSocket,这种方式更简单、更符合现代 Web 应用的需求。
核心概念
1. 服务器推送事件(SSE)简介
服务器推送事件(Server-Sent Events,SSE)是 HTML5 标准中的一部分,允许服务器通过 HTTP 协议主动向客户端发送消息。SSE 的特点是:
- 基于单向通信模型,服务器推送更新,客户端被动接收。
- 使用简单的 HTTP 协议而非 WebSocket 的自定义协议。
- 更容易通过现有的 HTTP 基础设施(如代理和缓存)进行优化。
然而,SSE 存在一些限制,如浏览器兼容性问题、无法原生支持多租户场景等。这正是 Mercure 协议设计的出发点。
2. Mercure 的工作原理
Mercure 基于 HTTP/2 和 HTTP/3 构建,扩展了 SSE 的功能,同时提供了一种便捷的机制来管理主题(topics)和订阅。
其核心组件包括:
- 1. Hub Hub 是 Mercure 的消息路由中心,负责接受来自发布者(Publisher)的消息并将其分发给订阅者(Subscriber)。
- 2. JWT 鉴权 Mercure 使用 JSON Web Tokens (JWT) 来进行访问控制,可以灵活地为不同的订阅者分配权限。
- 3. Discovery 机制 支持通过 HTTP 链接标头自动发现 Hub URL,无需硬编码配置。
3. 与 WebSocket 的对比
特性 | Mercure/SSE | WebSocket |
协议标准 | HTTP (基于 HTTP/2 或 HTTP/3) | 自定义协议 (TCP 上层) |
双向通信支持 | 否(单向:服务器到客户端) | 是(全双工通信) |
兼容性 | 支持 HTTP 基础设施,如缓存、代理 | 需要专门支持 |
简易性 | 简单,易于集成和维护 | 较复杂,需要更多开发投入 |
授权与鉴权 | 原生支持 JWT | 需要额外开发 |
应用场景
Mercure 非常适用于以下场景:
- 实时数据更新:如股票价格、天气预报、体育比赛分数。
- 协作型应用:如协作文档、多人游戏状态同步。
- 事件通知:如聊天应用中的消息推送、新订单提醒。
- 微服务间通信:通过主题机制实现事件驱动架构中的消息分发。
为什么推荐使用 Mercure?
1. 快速上手
只需运行官方的 Mercure Hub 即可开始使用,代码简单易集成:
- 订阅代码:
const url = new URL('https://localhost/.well-known/mercure');
url.searchParams.append('topic', 'https://example.com/books/{id}');
url.searchParams.append('topic', 'https://example.com/users/dunglas');
const eventSource = new EventSource(url);
eventSource.onmessage = e => console.log(e.data);
- 发布代码:
curl -d 'topic=https://example.com/books/1' -d 'data={"foo": "updated value"}' \
-H 'Authorization: Bearer ' -X POST https://localhost/.well-known/mercure
2. 性能和稳定性
- Mercure 使用了 HTTP/2,可以高效处理大量连接。
- 与传统轮询方式相比,大幅减少服务器资源占用。
3. 灵活的权限管理
JWT 的集成方式使得可以轻松实现精确到用户级别的授权和安全更新。
4. 丰富的生态和支持
除了官方实现,社区提供了多种语言的库,如 PHP、Node.js、Python 等,支持跨技术栈使用。
示例项目
架构设计
- 用户界面:单页应用,显示书籍库存及详细信息,订阅更新。
- 服务端:基于 Node.js 实现,管理书籍数据和事件发布。
- Mercure Hub:用作实时事件分发中心。
实现步骤
1、设置 Mercure Hub
安装官方 Docker 镜像或通过二进制文件运行。配置 JWT 密钥等参数。
2、订阅实时事件
在前端页面中,用户订阅感兴趣的书籍库存更新事件:
const url = new URL('https://localhost/.well-known/mercure');
url.searchParams.append('topic', 'https://example.com/books/{id}');
const eventSource = new EventSource(url);
eventSource.onmessage = e => updateUI(JSON.parse(e.data));
3、发布事件
当服务端库存更新时,通过 Mercure 推送实时变化:
const postData = querystring.stringify({
topic: 'https://example.com/books/1',
data: JSON.stringify({ stock: 42 }),
});
http.request({
hostname: 'localhost',
port: '3000',
path: '/.well-known/mercure',
method: 'POST',
headers: {
Authorization: `Bearer `,
'Content-Type': 'application/x-www-form-urlencoded',
},
}).write(postData);
4、优化 UI 体验
确保在组件销毁时关闭连接:
eventSource.close();
总结
Mercure 是一种高效、现代化的实时通信解决方案,具有广泛的适用性。其简单的设计和强大的功能特别适合我们团队快速实现实时功能,提高用户体验。