bentools/mercure-php-hub

此包已被废弃,不再维护。作者建议使用 freddie/mercure-x 包代替。

Mercure Hub 协议的 PHP 实现。

安装: 35

依赖者: 0

建议者: 0

安全: 0

星标: 21

关注者: 6

分支: 1

开放问题: 2

类型:项目

0.1 2021-01-03 13:17 UTC

This package is auto-updated.

Last update: 2021-12-18 13:00:05 UTC


README

CI Workflow codecov Scrutinizer Code Quality

Mercure PHP Hub

这个原型是一个 Mercure Hub 规范 的 PHP 实现。

由于我最近发布了 Freddie,该仓库将不再维护,Freddie 是一个全新的实现,它利用了 Framework X(底层仍然使用 ReactPHP)。

安装

要运行该 hub,需要 PHP 7.4+(以及 Redis,如果使用 Redis 转发器)。

composer create-project bentools/mercure-php-hub:dev-master

用法

./bin/mercure --jwt-key=\!ChangeMe\!

您可以使用环境变量(UPPER_SNAKE_CASE)来替换 CLI 选项,以便更方便。hub 还会检查是否存在 /etc/mercure/mercure.env 文件,然后使用 Symfony DotEnv 组件来填充变量。

请查看 configuration.php 以获取完整的配置选项。

优势和局限性

此实现不提供 SSL 或 HTTP2 终止,因此您最好在它前面放置一个反向代理。

使用 nginx 的示例

upstream mercure {
    server 127.0.0.1:3000;
}

server {
    
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com/example.com.cert;
    ssl_certificate_key /etc/ssl/certs/example.com/example.com.key;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

    location /.well-known/mercure {
        proxy_pass http://mercure;
        proxy_read_timeout 24h;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

默认情况下,hub 将作为简单的事件调度器运行。它可以满足基本使用的常见需求,但不可扩展(打开另一个进程不会共享相同的事件发射器)。

另一方面,您可以在 Redis 转发器(只要它们共享相同的 Redis 实例)上启动 hub,并在多个端口/服务器上使用负载均衡器来分发流量。由于 open-source Go 实现的 hub 在 bolt 转发器上的并发限制,这目前尚不可能。

upstream mercure {
    # 4 instances on 10.1.2.3
    server 10.1.2.3:3000;
    server 10.1.2.3:3001;
    server 10.1.2.3:3002;
    server 10.1.2.3:3003;

    # 4 instances on 10.1.2.4
    server 10.1.2.4:3000;
    server 10.1.2.4:3001;
    server 10.1.2.4:3002;
    server 10.1.2.4:3003;
}
./bin/mercure --transport-url="redis://localhost" --jwt-key=\!ChangeMe\!

基准测试

在服务器 A 上模拟 1/100/1000 订阅者,在服务器 B 上有 1 个发布者发送消息,服务器 C(以及服务器 D)上的 hub。

实现 传输 服务器 节点 1 订阅者 100 订阅者 1000 订阅者
Mercure.rocks GO Hub Bolt 1 1 361 / 286 129 / 4989 142 / 682
ReactPHP 实现 PHP 1 1 860 / 295 519 / 4526 45 / 322
ReactPHP 实现 Redis(本地) 1 1 1548 / 411 393 / 5861 112 / 777
ReactPHP 实现 Redis(本地) 1 4 108 / 76 61 / 2852 61 / 688
ReactPHP 实现 Redis(共享) 2 8 3035 / 144 1183 / 7864 708 / 2698

单位是 POSTs (发布) / s / 接收事件 / s(所有订阅者的总数)。

节点是 ReactPHP 打开的端口的总数。

Hub 在廉价的服务器上托管:2GB / 2 CPU VPS(Ubuntu 20.04)。您可以使用更大尺寸的服务器和专用 CPU 达到非常高的性能。

功能覆盖范围

功能 覆盖
通过 Authorization 头部使用 JWT
通过 mercureAuthorization Cookie 使用 JWT
为订阅者/发布者使用不同的 JWT
允许匿名订阅者
CORS
私有更新
主题的 URI 模板
健康检查端点
HMAC SHA256 JWT 签名
RS512 JWT 签名
环境变量配置
自定义消息 ID
最后事件 ID ✅️ (除了 REDIS 传输中的 earliest)
可定制事件类型 ✅️
可定制 retry 指令 ✅️
日志记录 ❌ (WIP)️
度量 ❌ (WIP)️
订阅事件 ❌️
订阅 API ❌️
使用配置文件进行配置 ❌️
有效负载 ❌️
心跳 ❌️
Forwarded / X-Forwarded-For 头部 ❌️
备用主题 ❌️

附加功能

此实现提供了一些在原始规范中未定义的功能。

订阅/发布主题排除

Mercure 利用 URI Templates 基于URI模式授权订阅和/或发布权限。

{
  "mercure": {
    "publish": [
      "https://example.com/items/{id}"
    ],
    "subscribe": [
      "https://example.com/items/{id}"
    ]
  }
}

但是,拒绝访问与URI模板匹配的特定URL需要您显式列出授权项。

{
  "mercure": {
    "publish": [
      "https://example.com/items/1",
      "https://example.com/items/2",
      "https://example.com/items/4"
    ],
    "subscribe": [
      "https://example.com/items/1",
      "https://example.com/items/2",
      "https://example.com/items/4"
    ]
  }
}

当处理成千上万的可能性时,这可能会很快成为一个问题。Mercure PHP Hub 允许您通过 publish_excludesubscribe_exclude 键指定拒绝列表,这些键接受任何主题选择器。

{
  "mercure": {
    "publish": [
      "https://example.com/items/{id}"
    ],
    "publish_exclude": [
      "https://example.com/items/3"
    ],
    "subscribe": [
      "https://example.com/items/{id}"
    ],
    "subscribe_exclude": [
      "https://example.com/items/3"
    ]
  }
}

Json Web Token 生成器

您可以从命令行生成一个 JWT,用于在中心使用。

./bin/mercure jwt:generate

它将交互式地询问您希望允许/拒绝哪些主题选择器用于发布/订阅,并询问您一个可选的TTL。

如果您想要原始输出(例如,将生成的 JWT 管道),请使用 --raw 选项。

要禁用交互,可以使用以下示例

./bin/mercure jwt:generate --no-interactive --publish=/foo/{id} --publish=/bar --publish-exclude=/foo/bar

它将使用您的 JWT 密钥环境变量,或者您可以使用 --jwt-key--publisher-jwt-key--subscriber-jwt-key 选项。

要获取可用选项的完整列表,请运行此

./bin/mercure jwt:generate -h

测试

此项目受到 Pest 测试的覆盖。覆盖率需要提高:请随时贡献力量。

composer tests:run

贡献力量

如果您想改进此项目,请随时提交 PR。

  • CI 会大声喊叫,如果您不遵循 PSR-12 编码标准
  • 在新的功能中,它必须伴随着测试。
  • PHPStan 分析必须在第 5 级通过。

在提交之前,您可以使用 composer ci:check 运行以确保所有 CI 要求都已成功满足。

许可证

GNU 通用公共许可证 v3.0。