Laravel 13.x:Reverb
简介
Laravel Reverb 为 Laravel 应用提供高速、可扩展的实时 WebSocket 通信,并与现有事件广播工具 无缝集成。
安装
使用 Artisan 命令 install:broadcasting 安装 Reverb:
php artisan install:broadcasting
配置
install:broadcasting 在内部运行 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
允许的来源
可以修改 config/reverb.php 中 apps 部分的 allowed_origins,规定客户端请求可来自哪些来源。不在列表中的来源会被拒绝;使用 * 可允许所有来源:
'apps' => [
[
'app_id' => 'my-app-id',
'allowed_origins' => ['laravel.com'],
// ...
]
]
多个应用
通常,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 环境变量设为站点主机名,或启动服务器时显式传入 hostname 选项:
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"
Herd 和 Valet 域名解析到 localhost,因此运行以上命令后,可以通过安全 WebSocket 协议 wss,在 wss://laravel.test:8080 访问 Reverb。
也可以在 config/reverb.php 中定义 tls 选项手动选择证书。该数组接受 PHP SSL 上下文 支持的任意选项:
'options' => [
'tls' => [
'local_cert' => '/path/to/cert.pem'
],
],
运行服务器
使用 Artisan 命令 reverb:start 启动服务器:
php artisan reverb:start
默认监听 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
调试
为提高性能,Reverb 默认不输出调试信息。要查看经过服务器的数据流,可为 reverb:start 添加 --debug:
php artisan reverb:start --debug
重启
Reverb 是长期运行的进程,代码变化必须通过 Artisan 命令 reverb:restart 重启服务器后才会生效。
该命令会在停止服务器之前正常关闭所有连接。如果使用 Supervisor 等进程管理器,连接全部关闭后,进程管理器会自动重启服务器:
php artisan reverb:restart
监控
Reverb 可以通过 Laravel 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 仪表盘 中加入每个记录器对应的卡片:
<x-pulse>
<livewire:reverb.connections cols="full" />
<livewire:reverb.messages cols="full" />
...
</x-pulse>
连接活动通过定期轮询更新来记录。为确保 Pulse 仪表盘正确展示,必须在 Reverb 服务器运行 pulse:check 守护进程。如果 Reverb 采用水平扩展,只应在其中一台服务器运行该进程。
在生产环境运行 Reverb
由于 WebSocket 服务器长期运行,可能需要优化服务器和托管环境,才能充分利用可用资源处理尽可能多的连接。
> 注意
> Laravel Cloud 提供由 Reverb 集群支撑的完全托管 WebSocket 基础设施,便于在无需管理基础设施的情况下部署和扩展使用 Reverb 的应用。
打开的文件
每个 WebSocket 连接在客户端或服务器断开前都会保留在内存中。在 Unix 和类 Unix 环境中,每个连接由一个文件表示;操作系统和应用通常都对打开的文件数量设有限制。
操作系统
在 Unix 类操作系统中,可以用 ulimit 查看允许打开的文件数:
ulimit -n
该命令显示允许打开的文件数量限制。可编辑 /etc/security/limits.conf 调整不同用户的限制。例如,把 forge 用户的最大打开文件数改为 10,000:
# /etc/security/limits.conf
forge soft nofile 10000
forge hard nofile 10000
事件循环
Reverb 使用 ReactPHP 事件循环管理 WebSocket 连接。默认循环基于 stream_select,不需要额外扩展,但通常最多支持 1,024 个打开的文件。因此,计划处理超过 1,000 个并发连接时,需要使用不受相同限制的其他事件循环。
可用时,Reverb 会自动切换为基于 ext-uv 的事件循环。该 PHP 扩展可通过 PECL 安装:
pecl install uv
Web 服务器
Reverb 通常监听不直接面向公网的端口,因此需要配置反向代理。假设 Reverb 监听 0.0.0.0:8080,Web 服务器使用 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;
}
...
}
> 注意
> Reverb 在 /app 监听 WebSocket 连接,在 /apps 处理 API 请求。处理 Reverb 请求的 Web 服务器必须支持这两个 URI。使用 Laravel Forge 管理服务器时,默认配置已正确处理。
Web 服务器通常会限制连接数量以避免过载。要把 Nginx 允许的连接数提高到 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;
}
原文将以上配置描述为每个进程最多产生 10,000 个 Nginx worker,并将 Nginx 的打开文件数限制设为 10,000。
端口
Unix 类操作系统通常限制服务器可打开的端口范围。可以用以下命令查看当前范围:
cat /proc/sys/net/ipv4/ip_local_port_range
# 32768 60999
原文根据以上输出,将连接上限计算为 28,231(60,999 − 32,768),理由是每个连接需要一个空闲端口。文档推荐用水平扩展 增加连接容量;也可以修改 /etc/sysctl.conf 中允许的端口范围以增加可用端口。
进程管理
通常应使用 Supervisor 等进程管理器确保 Reverb 持续运行。使用 Supervisor 时,应调整 supervisor.conf 中的 minfds,确保它能够打开处理 Reverb 连接所需的文件:
[supervisord]
...
minfds=10000
水平扩展
需要处理超出单台服务器容量的连接时,可以水平扩展 Reverb。它利用 Redis 发布/订阅能力跨服务器管理连接。当应用的一台 Reverb 服务器收到消息时,会通过 Redis 把消息发布给其他所有服务器。
要启用水平扩展,在 .env 中把 REVERB_SCALING_ENABLED 设为 true:
REVERB_SCALING_ENABLED=true
接着,需要一台所有 Reverb 服务器均可访问的专用中央 Redis 服务器。Reverb 使用应用默认 Redis 连接,向所有 Reverb 服务器发布消息。
启用扩展选项并配置 Redis 后,在能访问 Redis 的多台服务器上运行 reverb:start 即可。把这些 Reverb 服务器放在负载均衡器之后,由负载均衡器均匀分配传入请求。
事件
Reverb 在连接生命周期和消息处理期间派发内部事件。可以监听这些事件,在连接管理或消息交换时执行操作。
Reverb 会派发以下事件:
Laravel\Reverb\Events\ChannelCreated
创建频道时派发,通常发生于第一个连接订阅某个频道时。事件接收 Laravel\Reverb\Protocols\Pusher\Channel 实例。
Laravel\Reverb\Events\ChannelRemoved
移除频道时派发,通常发生于最后一个连接退订某个频道时。事件接收 Laravel\Reverb\Protocols\Pusher\Channel 实例。
Laravel\Reverb\Events\ConnectionPruned
服务器清理失效连接时派发,事件接收 Laravel\Reverb\Contracts\Connection 实例。
Laravel\Reverb\Events\MessageReceived
收到客户端连接发来的消息时派发,事件接收 Laravel\Reverb\Contracts\Connection 实例和原始字符串 $message。
Laravel\Reverb\Events\MessageSent
向客户端连接发送消息时派发,事件接收 Laravel\Reverb\Contracts\Connection 实例和原始字符串 $message。
来源:Laravel Reverb,对应 Laravel 13.x 文档。© Taylor Otwell;遵循 MIT 许可证。
MIT 许可声明
Copyright (c) Taylor Otwell
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.











暂无评论内容