Laravel Reverb
介绍
Laravel Reverb 为你的 Laravel 应用带来了快速的、可扩展的实时 WebSocket 通信,并提供与 Laravel 现有事件广播工具套件的无缝集成。
安装
你可以使用 install:broadcasting Artisan 命令安装 Reverb:
php artisan install:broadcasting配置
在底层,install:broadcasting Artisan 命令会运行 reverb:install 命令,它会使用一系列合理的默认配置选项来安装 Reverb。如果你想要更改任何配置选项,可以通过更新 Reverb 的环境变量或者更新 config/reverb.php 配置文件来进行。
应用凭证
为了建立与 Reverb 的连接,必须在客户端和服务器之间交换一组 Reverb 「应用程序」凭据。这些凭据在服务器上配置,用于验证来自客户端的请求。你可以使用以下环境变量定义这些凭据:
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret允许的来源(Allowed Origins)
你也可以通过更新 config/reverb.php 配置文件中 apps 部分的 allowed_origins 配置值来定义客户端请求可以来源的域。任何不在允许来源列表中的请求都会被拒绝。你可以使用 * 来允许所有来源:
'apps' => [
[
'app_id' => 'my-app-id',
'allowed_origins' => ['laravel.com'],
// ...
]
]额外应用(Additional Applications)
通常情况下,Reverb 会为安装它的应用提供一个 WebSocket 服务器。然而,也可以使用单个 Reverb 安装为多个应用提供服务。
例如,你可能希望维护一个单一的 Laravel 应用,通过 Reverb 为多个应用提供 WebSocket 连接。这可以通过在应用的 config/reverb.php 配置文件中定义多个 apps 来实现:
'apps' => [
[
'app_id' => 'my-app-one',
// ...
],
[
'app_id' => 'my-app-two',
// ...
],
],SSL
在大多数情况下,安全的 WebSocket 连接由上游 Web 服务器(如 Nginx)处理,然后再将请求代理到你的 Reverb 服务器。
但是,有时在本地开发期间,让 Reverb 服务器直接处理安全连接会很有用。如果你使用 Laravel Herd 的安全站点功能,或者使用 Laravel Valet 并对你的应用运行了 secure 命令,你可以使用为你的网站生成的 Herd / Valet 证书来保护 Reverb 连接。为此,将 REVERB_HOST 环境变量设置为你站点的主机名,或者在启动 Reverb 服务器时显式传递 hostname 选项:
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 上下文选项 支持的任何选项:
'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],启动服务器(Running the Server)
Reverb 服务器可以通过 reverb:start Artisan 命令启动:
php artisan reverb:start默认情况下,Reverb 服务器会启动在 0.0.0.0:8080,使其可从所有网络接口访问。
如果需要指定自定义主机或端口,可以在启动服务器时通过 --host 和 --port 选项实现:
php artisan reverb:start --host=127.0.0.1 --port=9000或者,你也可以在应用的 .env 配置文件中定义 REVERB_SERVER_HOST 和 REVERB_SERVER_PORT 环境变量。
需要注意的是,REVERB_SERVER_HOST 和 REVERB_SERVER_PORT 环境变量不要与 REVERB_HOST 和 REVERB_PORT 混淆。前者指定 Reverb 服务器自身运行的主机和端口,而后者用于告诉 Laravel 向哪里发送广播消息。例如,在生产环境中,你可以将公共 Reverb 主机名的 443 端口请求路由到运行在 0.0.0.0:8080 的 Reverb 服务器。在这种情况下,你的环境变量可以这样定义:
REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080
REVERB_HOST=ws.laravel.com
REVERB_PORT=443调试(Debugging)
为了提升性能,Reverb 默认不会输出任何调试信息。如果你希望查看通过 Reverb 服务器传输的数据流,可以在运行 reverb:start 命令时添加 --debug 选项:
php artisan reverb:start --debug重启(Restarting)
由于 Reverb 是一个长时间运行的进程,对代码的修改在不重启服务器的情况下不会生效。你需要通过 reverb:restart Artisan 命令来重启服务器。
reverb:restart 命令会在停止服务器之前,确保所有连接被优雅地终止。如果你使用 Supervisor 等进程管理器运行 Reverb,所有连接终止后,进程管理器会自动重启服务器:
php artisan reverb:restart监控(Monitoring)
Reverb 可以通过与 Laravel Pulse 的集成进行监控。启用 Reverb 的 Pulse 集成后,你可以跟踪服务器处理的连接数和消息数量。
要启用该集成,首先需要确保你已经 安装 Pulse。然后,将 Reverb 的任意记录器添加到应用的 config/pulse.php 配置文件中:
use Laravel\Reverb\Pulse\Recorders\ReverbConnections;
use Laravel\Reverb\Pulse\Recorders\ReverbMessages;
'recorders' => [
ReverbConnections::class => [
'sample_rate' => 1,
],
ReverbMessages::class => [
'sample_rate' => 1,
],
// ...
],接下来,将每个记录器的 Pulse 卡片添加到你的 Pulse 仪表盘:
<x-pulse>
<livewire:reverb.connections cols="full" />
<livewire:reverb.messages cols="full" />
...
</x-pulse>连接活动通过定期轮询新更新进行记录。为了确保这些信息在 Pulse 仪表盘上正确显示,你必须在 Reverb 服务器上运行 pulse:check 守护进程。如果你在 水平扩展 配置中运行 Reverb,该守护进程只需要在其中一台服务器上运行即可。
在生产环境中运行 Reverb(Running Reverb in Production)
由于 WebSocket 服务器是长时间运行的,你可能需要对服务器和托管环境进行一些优化,以确保你的 Reverb 服务器能够根据服务器可用资源有效处理最佳数量的连接。
Note
如果你的网站由 Laravel Forge 管理,你可以直接在“应用程序”面板中自动优化服务器以支持 Reverb。启用 Reverb 集成后,Forge 会确保服务器具备生产环境准备条件,包括安装所需扩展以及增加允许的连接数量。
打开的文件(Open Files)
每个 WebSocket 连接会保存在内存中,直到客户端或服务器断开连接。在 Unix 和类 Unix 系统中,每个连接都对应一个文件。然而,操作系统和应用程序级别通常对允许打开的文件数量有限制。
操作系统(Operating System)
在基于 Unix 的操作系统中,你可以使用 ulimit 命令查看允许打开的文件数量:
ulimit -n此命令会显示不同用户允许的打开文件限制。你可以通过编辑 /etc/security/limits.conf 文件来更新这些值。例如,将 forge 用户的最大打开文件数更新为 10,000,可以这样设置:
# /etc/security/limits.conf
forge soft nofile 10000
forge hard nofile 10000事件循环(Event Loop)
在底层,Reverb 使用 ReactPHP 事件循环来管理服务器上的 WebSocket 连接。默认情况下,该事件循环由 stream_select 提供支持,它不需要额外的扩展。然而,stream_select 通常限制在 1,024 个打开文件。因此,如果你计划处理超过 1,000 个并发连接,你需要使用不受同样限制的替代事件循环。
Reverb 在可用时会自动切换到由 ext-uv 提供支持的事件循环。这个 PHP 扩展可以通过 PECL 安装:
pecl install uvWeb 服务器(Web Server)
在大多数情况下,Reverb 在服务器上运行于非面向 Web 的端口。因此,为了将流量路由到 Reverb,你应配置反向代理。假设 Reverb 运行在主机 0.0.0.0 和端口 8080 上,并且你的服务器使用 Nginx Web 服务器,可以通过以下 Nginx 站点配置为 Reverb 服务器定义反向代理:
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;
}
...
}Warning
Reverb 在 /app 监听 WebSocket 连接,并在 /apps 处理 API 请求。你应确保处理 Reverb 请求的 Web 服务器可以提供这两个 URI。如果你使用 Laravel Forge 管理服务器,Reverb 服务器默认会被正确配置。
通常,Web 服务器会限制允许的连接数量,以防止服务器过载。要将 Nginx Web 服务器允许的连接数增加到 10,000,需要更新 nginx.conf 文件中的 worker_rlimit_nofile 和 worker_connections 值:
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;
}上述配置将允许每个 Nginx 进程生成最多 10,000 个工作进程。此外,该配置将 Nginx 的打开文件限制设置为 10,000。
端口(Ports)
基于 Unix 的操作系统通常会限制服务器上可打开的端口数量。你可以通过以下命令查看当前允许的端口范围:
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768 60999上面的输出显示服务器最多可以处理 28,231(60,999 - 32,768)个连接,因为每个连接都需要一个可用端口。虽然我们推荐使用水平扩展来增加允许的连接数,你也可以通过更新服务器 /etc/sysctl.conf 配置文件中的允许端口范围来增加可用的开放端口数量。
进程管理(Process Management)
在大多数情况下,你应使用进程管理器(如 Supervisor)来确保 Reverb 服务器持续运行。如果你使用 Supervisor 来运行 Reverb,应更新服务器 supervisor.conf 文件中的 minfds 设置,以确保 Supervisor 能够打开处理 Reverb 服务器连接所需的文件:
[supervisord]
...
minfds=10000扩展(Scaling)
如果你需要处理的连接数量超过单台服务器允许的数量,可以通过水平扩展 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 服务器应放置在负载均衡器后面,以便将传入请求均匀分配到各个服务器。
本译文转载自 Laravel China 社区 组织翻译的 Laravel 中文文档。原文链接:https://learnku.com/docs/laravel/12.x/reverb/17019