frankenphp内置mercure时,访问地址为https://www.php.cn/link/e925ccdfbd16ff62129653dcefd1745d;它集成在caddy http链中,不监听独立端口,路径固定,主机名由caddyfile site定义,php同容器内可直接用localhost,需确保mercure指令启用且jwt密钥配齐。

FrankenPHP 内置 Mercure 时,访问地址就是 https://www.php.cn/link/e925ccdfbd16ff62129653dcefd1745d
FrankenPHP 启用 Mercure 后,它不是跑在独立端口(比如 :3000)上的外部服务,而是直接集成在 Caddy 的 HTTP 处理链中。所有 Mercure 请求都走标准 HTTP 路由,路径固定为 /.well-known/mercure,主机名取决于你 Caddyfile 中定义的 site。
- 如果 Caddyfile 是
localhost { ... },那发布地址就是@#@#@#@#@#@#@#@#@#@0 - 如果配的是
myapp.test { ... },且本地 hosts 指向 127.0.0.1,则用@#@#@#@#@#@#@#@#@#@1 - Docker 环境下 PHP 进程若和 FrankenPHP 在同一容器内(推荐),
localhost仍有效;若跨容器(不推荐),必须用容器名(如@#@#@#@#@#@#@#@#@#@2),并确保网络互通
不要试图改成 @#@#@#@#@#@#@#@#@#@3 或其他端口——FrankenPHP 内置 Mercure 不监听额外端口,也没有 --addr 参数可调。
用 curl 测试 Mercure 地址是否生效
最直接的验证方式是发一个 GET 请求看 discovery 响应:
- 运行
curl -v @#@#@#@#@#@#@#@#@#@0 - 正确响应:HTTP 200 + JSON,含
{"hub":"...","subscriber":"..."}字段 - 常见错误:
-
404 Not Found:Caddyfile 中没启用mercure指令块,或该指令被注释 -
500 Internal Server Error:JWT 密钥为空、格式错误,或publisher_jwt和subscriber_jwt没配齐 -
Connection refused:FrankenPHP 根本没起来,或端口没映射对(Docker 下漏了-p 8000:8000)
-
注意:这个地址只用于发布(POST)和 discovery(GET),订阅端(EventSource)也必须用完全相同的 URL,不能加端口号、不能换协议(即不能用 https 除非你已配好 TLS)。
Symfony 或 Laravel 里怎么填 hub_url
框架配置里必须写成和实际请求路径完全一致的地址:
- 开发环境(FrankenPHP 本地运行):
hub_url: '@#@#@#@#@#@#@#@#@#@0' - 生产环境(通过域名访问):
hub_url: '@#@#@#@#@#@#@#@#@#@6'(前提是 Caddyfile 已配好 HTTPS 自动签发) - 绝对不要填
@#@#@#@#@#@#@#@#@#@7或@#@#@#@#@#@#@#@#@#@8—— 这是外部 Mercure 部署才用的地址,和 FrankenPHP 内置模式冲突
Symfony 的 config/packages/mercure.yaml 中若还保留 MERCURE_PUBLISH_URL 环境变量引用,要删掉;Laravel 的 .env 里同理清空相关变量。FrankenPHP 的 JWT 密钥来自 Caddyfile,不走环境变量。
为什么不能用反向代理改 Mercure 地址
有人想在 Caddyfile 里用 reverse_proxy 把 /.well-known/mercure 转到别的地方,这是徒劳的:
- FrankenPHP 的 Mercure 模块只响应它自己处理的路径,一旦被
reverse_proxy拦截,就绕过了内置 Hub -
mercure指令必须出现在 Caddyfile 的 site block 顶层,不能嵌套在路由规则里 - 若你真需要代理(比如前置 Nginx),那 Mercure 就不该用 FrankenPHP 内置,而该换成独立
dunglas/mercure容器 —— 二者不可混用
真正起作用的只有这一段(放在 Caddyfile 的 site block 内):
mercure {
publisher_jwt !ChangeThisMercureHubJWTSecretKey!
subscriber_jwt !ChangeThisMercureHubJWTSecretKey!
anonymous
}
地址本身没有“配置项”,它是协议约定死的路径。你唯一能控制的,是这个路径绑定在哪个 host、是否启用 HTTPS、以及背后 JWT 密钥是否匹配。
复杂点在于:地址看似简单,但任何一环(Caddyfile 结构、JWT 字段、网络可达性、框架配置)出错,都会导致 /.well-known/mercure 表面通、实际拒收请求。调试时优先确认 curl GET 返回的是有效 JSON,再动 POST。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











