mercure 不依赖 redis pub/sub,其 hub 内置基于 http/2 sse 的事件广播机制,直接通过 publish() 方法接收事件并推送给客户端;若需 redis 变更触发 mercure 通知,须手动实现监听与转发逻辑。

Mercure 本身不依赖 Redis Pub/Sub,它用的是内置的事件分发器
Mercure 的核心设计是基于 HTTP/2 Server-Sent Events(SSE),它的 Hub 组件(比如 FrankenPHP 内置的 Mercure Hub)自己维护连接状态和事件广播逻辑。它不通过 Redis 的 SUBSCRIBE 或 PUBLISH 做消息中转,也不监听 Redis 频道。你直接调用 publish() 方法向 Hub 推送事件,Hub 内部完成广播。
这意味着:
- 不需要在 PHP 里写
$redis->publish('mercure', $event)这类桥接代码 - 也不用起一个后台进程去
SUBSCRIBE某个频道再转发给 Mercure - Mercure 的事件生命周期完全独立于 Redis 连接
想让 Redis 数据变更触发 Mercure 通知?得自己写胶水逻辑
如果你的业务场景是「Redis 中某个 key 变了,就推一条 Mercure 事件给前端」,那必须手动实现监听 + 转发。常见做法是:
- 使用 Redis 的
KEYSPACE或KEYEVENT通知(需开启notify-keyspace-events配置) - 或轮询 +
SCAN+GET对比(不推荐,延迟高) - 或在业务代码里,每次写 Redis 后主动调用 Mercure
publish()
例如,在 PHP 中更新用户状态后:
// 更新 Redis
$redis->set('user:123:status', 'online');
<p>// 同步触发 Mercure 事件(不是靠 Redis 自动推送)
$hub = new Hub('<a href="https://www.php.cn/link/88fb5c7695333f12a8d9742e0f166e25">https://www.php.cn/link/88fb5c7695333f12a8d9742e0f166e25</a>', $jwt);
$hub->publish(new Update('/users/123', json_encode(['status' => 'online'])));
</p>
注意:这个过程是「业务层双写」,不是自动同步。Redis 和 Mercure 之间没有内置管道。
用 Redis Stream 替代 Pub/Sub 做可靠事件总线时,Mercure 仍不参与消费
有人会想:「我用 Redis Stream 存事件日志,再让 Mercure 消费 Stream 并广播」——这不可行。Mercure Hub 不提供消费者组、不读 XREADGROUP、不 ACK 消息。它只响应来自应用层的 HTTP POST 请求(/.well-known/mercure)。
如果你需要这种链路,得自己写一个常驻进程(如 Swoole Worker 或 Symfony CLI command):
- 监听 Redis Stream(
XREADGROUP GROUP mercure-consumer ...) - 解析事件内容
- 构造 Mercure
Update并调用$hub->publish() - 手动
XACK
否则,Stream 里的事件只会堆积,Mercure 完全无感。
真正要警惕的坑:别混淆 Mercure Hub 和 Redis Pub/Sub 的语义边界
- Mercure 是面向客户端的实时推送协议,关注「谁订阅了哪些 IRI(URL)」
- Redis Pub/Sub 是服务端进程间通信机制,关注「谁连着哪个 channel」
- 两者模型不兼容:Mercure 订阅基于 JWT 主题白名单(
subscribeclaim),Redis 订阅基于字符串频道名 - 混用时最容易犯的错是:以为
SUBSCRIBE mercure就能让 Mercure 收到消息,其实它根本没在监听这个频道
所以,该用 Redis 的地方用 Redis(比如内部微服务通信),该用 Mercure 的地方用 Mercure(比如向浏览器推送状态变更),中间那层联动逻辑,必须由你亲手缝合,且要处理好失败重试、重复投递、连接断开等细节。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











