Skip to content

Laravel Reverb

介绍

Laravel Reverb 为您的 Laravel 应用程序带来了快速且可扩展的实时 WebSocket 通信,并与 Laravel 现有的事件广播工具套件无缝集成。

安装

exclamation

Laravel Reverb 需要 PHP 8.2+ 和 Laravel 10.47+。

您可以使用 Composer 包管理器将 Reverb 安装到您的 Laravel 项目中:

sh
composer require laravel/reverb

安装包后,您可以运行 Reverb 的安装命令来发布配置,添加 Reverb 所需的环境变量,并在您的应用程序中启用事件广播:

sh
php artisan reverb:install

配置

reverb:install 命令将自动使用一组合理的默认选项配置 Reverb。如果您想进行任何配置更改,可以通过更新 Reverb 的环境变量或更新 config/reverb.php 配置文件来实现。

应用凭证

为了建立与 Reverb 的连接,客户端和服务器之间必须交换一组 Reverb "应用" 凭证。这些凭证在服务器上配置,用于验证来自客户端的请求。您可以使用以下环境变量定义这些凭证:

ini
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret

允许的来源

您还可以通过更新 config/reverb.php 配置文件中 apps 部分的 allowed_origins 配置值来定义客户端请求可能来源的来源。任何来自未列入允许来源的请求将被拒绝。您可以使用 * 允许所有来源:

php
'apps' => [
    [
        'id' => 'my-app-id',
        'allowed_origins' => ['laravel.com'],
        // ...
    ]
]

附加应用

通常,Reverb 为其安装的应用程序提供 WebSocket 服务器。然而,可以使用单个 Reverb 安装为多个应用程序提供服务。

例如,您可能希望维护一个单一的 Laravel 应用程序,通过 Reverb 为多个应用程序提供 WebSocket 连接。这可以通过在应用程序的 config/reverb.php 配置文件中定义多个 apps 来实现:

php
'apps' => [
    [
        'app_id' => 'my-app-one',
        // ...
    ],
    [
        'app_id' => 'my-app-two',
        // ...
    ],
],

SSL

在大多数情况下,安全的 WebSocket 连接可能由上游 Web 服务器(如 Nginx 等)处理,然后请求被代理到您的 Reverb 服务器。

然而,在本地开发期间,Reverb 服务器直接处理安全连接有时是有用的。如果您使用 Laravel Herd 的安全站点功能,或者您使用 Laravel Valet 并对您的应用程序运行了 secure command,您可以使用为您的站点生成的 Herd / Valet 证书来保护您的 Reverb 连接。为此,请将 REVERB_HOST 环境变量设置为您的站点主机名,或在启动 Reverb 服务器时显式传递主机名选项:

sh
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"

由于 Herd 和 Valet 域解析为 localhost,运行上述命令将使您的 Reverb 服务器可以通过安全的 WebSocket 协议(wss)在 wss://laravel.test:8080 访问。

您还可以通过在应用程序的 config/reverb.php 配置文件中定义 tls 选项来手动选择证书。在 tls 选项数组中,您可以提供 PHP 的 SSL 上下文选项 支持的任何选项:

php
'options' => [
    'tls' => [
        'local_cert' => '/path/to/cert.pem'
    ],
],

运行服务器

可以使用 reverb:start Artisan 命令启动 Reverb 服务器:

sh
php artisan reverb:start

默认情况下,Reverb 服务器将在 0.0.0.0:8080 启动,使其可以从所有网络接口访问。

如果您需要指定自定义主机或端口,可以在启动服务器时通过 --host--port 选项来实现:

sh
php artisan reverb:start --host=127.0.0.1 --port=9000

或者,您可以在应用程序的 .env 配置文件中定义 REVERB_SERVER_HOSTREVERB_SERVER_PORT 环境变量。

REVERB_SERVER_HOSTREVERB_SERVER_PORT 环境变量不应与 REVERB_HOSTREVERB_PORT 混淆。前者指定运行 Reverb 服务器本身的主机和端口,而后者指示 Laravel 将广播消息发送到哪里。例如,在生产环境中,您可以将来自公共 Reverb 主机名的请求从端口 443 路由到在 0.0.0.0:8080 上运行的 Reverb 服务器。在这种情况下,您的环境变量将定义如下:

ini
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080

REVERB_HOST=ws.laravel.com
REVERB_PORT=443

调试

为了提高性能,Reverb 默认不输出任何调试信息。如果您想查看通过您的 Reverb 服务器的数据流,可以为 reverb:start 命令提供 --debug 选项:

sh
php artisan reverb:start --debug

重启

由于 Reverb 是一个长时间运行的进程,代码的更改不会在不重启服务器的情况下反映出来。可以通过 reverb:restart Artisan 命令重启服务器。

reverb:restart 命令确保在停止服务器之前,所有连接都被优雅地终止。如果您使用像 Supervisor 这样的进程管理器运行 Reverb,进程管理器将在所有连接终止后自动重启服务器:

sh
php artisan reverb:restart

在生产环境中运行 Reverb

由于 WebSocket 服务器的长时间运行特性,您可能需要对服务器和托管环境进行一些优化,以确保您的 Reverb 服务器能够有效处理服务器上可用资源的最佳连接数。

lightbulb

如果您的站点由 Laravel Forge 管理,您可以直接从“应用程序”面板自动优化您的服务器以支持 Reverb。通过启用 Reverb 集成,Forge 将确保您的服务器已准备好生产,包括安装任何所需的扩展并增加允许的连接数。

打开文件

每个 WebSocket 连接都保存在内存中,直到客户端或服务器断开连接。在 Unix 和类 Unix 环境中,每个连接都由一个文件表示。然而,操作系统和应用程序级别通常对允许的打开文件数量有限制。

操作系统

在基于 Unix 的操作系统上,您可以使用 ulimit 命令确定允许的打开文件数量:

sh
ulimit -n

此命令将显示不同用户允许的打开文件限制。您可以通过编辑 /etc/security/limits.conf 文件来更新这些值。例如,将 forge 用户的最大打开文件数更新为 10,000 如下所示:

ini
# /etc/security/limits.conf
forge        soft  nofile  10000
forge        hard  nofile  10000

事件循环

在底层,Reverb 使用 ReactPHP 事件循环来管理服务器上的 WebSocket 连接。默认情况下,此事件循环由 stream_select 驱动,不需要任何额外的扩展。然而,stream_select 通常限制为 1,024 个打开文件。因此,如果您计划处理超过 1,000 个并发连接,您将需要使用不受相同限制的替代事件循环。

Reverb 将在可用时自动切换到由 ext-eventext-evext-uv 驱动的循环。所有这些 PHP 扩展都可以通过 PECL 安装:

sh
pecl install event
# 或
pecl install ev
# 或
pecl install uv

Web 服务器

在大多数情况下,Reverb 在服务器上的非 Web 面向端口上运行。因此,为了将流量路由到 Reverb,您应该配置反向代理。假设 Reverb 在主机 0.0.0.0 和端口 8080 上运行,并且您的服务器使用 Nginx Web 服务器,可以使用以下 Nginx 站点配置为您的 Reverb 服务器定义反向代理:

nginx
server {
    ...

    location / {
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_pass http://0.0.0.0:8080;
    }

    ...
}

通常,Web 服务器配置为限制允许的连接数量,以防止服务器过载。要将 Nginx Web 服务器上的允许连接数增加到 10,000,应更新 nginx.conf 文件的 worker_rlimit_nofileworker_connections 值:

nginx
user forge;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
worker_rlimit_nofile 10000;

events {
  worker_connections 10000;
  multi_accept on;
}

上述配置将允许每个进程最多生成 10,000 个 Nginx 工作进程。此外,此配置将 Nginx 的打开文件限制设置为 10,000。

端口

基于 Unix 的操作系统通常限制服务器上可以打开的端口数量。您可以通过以下命令查看当前允许的范围:

sh
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768	60999

上面的输出显示服务器可以处理最多 28,231(60,999 - 32,768)个连接,因为每个连接都需要一个空闲端口。尽管我们建议 水平扩展 来增加允许的连接数,但您可以通过更新服务器的 /etc/sysctl.conf 配置文件中的允许端口范围来增加可用的开放端口数量。

进程管理

在大多数情况下,您应该使用像 Supervisor 这样的进程管理器来确保 Reverb 服务器持续运行。如果您使用 Supervisor 运行 Reverb,您应该更新服务器的 supervisor.conf 文件的 minfds 设置,以确保 Supervisor 能够打开处理与 Reverb 服务器连接所需的文件:

ini
[supervisord]
...
minfds=10000

扩展

如果您需要处理比单个服务器允许的更多连接,您可以水平扩展您的 Reverb 服务器。利用 Redis 的发布/订阅功能,Reverb 能够跨多个服务器管理连接。当您的应用程序的一个 Reverb 服务器接收到消息时,服务器将使用 Redis 将传入消息发布到所有其他服务器。

要启用水平扩展,您应该在应用程序的 .env 配置文件中将 REVERB_SCALING_ENABLED 环境变量设置为 true

REVERB_SCALING_ENABLED=true

接下来,您应该有一个专用的中央 Redis 服务器,所有 Reverb 服务器都将与之通信。Reverb 将使用 为您的应用程序配置的默认 Redis 连接 将消息发布到所有 Reverb 服务器。

一旦您启用了 Reverb 的扩展选项并配置了 Redis 服务器,您可以简单地在能够与您的 Redis 服务器通信的多个服务器上调用 reverb:start 命令。这些 Reverb 服务器应放置在一个负载均衡器后面,该负载均衡器将传入请求均匀分配到各个服务器。