Laravel Reverb
簡介
Laravel Reverb 將閃電般快速且可擴展的即時 WebSocket 通訊直接帶入您的 Laravel 應用程式,並提供與 Laravel 現有的 事件廣播工具 套件無縫整合。
安裝
您可以使用 install:broadcasting
Artisan 命令安裝 Reverb
1php artisan install:broadcasting
設定
在幕後,install:broadcasting
Artisan 命令將執行 reverb:install
命令,這將使用合理的預設配置選項安裝 Reverb。如果您想進行任何配置更改,您可以通過更新 Reverb 的環境變數或更新 config/reverb.php
配置檔案來完成。
應用程式憑證
為了建立與 Reverb 的連線,客戶端和伺服器之間必須交換一組 Reverb「應用程式」憑證。這些憑證在伺服器上配置,用於驗證來自客戶端的請求。您可以使用以下環境變數定義這些憑證
1REVERB_APP_ID=my-app-id2REVERB_APP_KEY=my-app-key3REVERB_APP_SECRET=my-app-secret
允許的來源
您還可以通過更新 config/reverb.php
配置檔案的 apps
區段中 allowed_origins
配置值的值,來定義客戶端請求可以來自的來源。來自未在您的允許來源中列出的來源的任何請求都將被拒絕。您可以使用 *
允許所有來源
1'apps' => [2 [3 'app_id' => 'my-app-id',4 'allowed_origins' => ['laravel.com'],5 // ...6 ]7]
額外的應用程式
通常,Reverb 為安裝它的應用程式提供 WebSocket 伺服器。但是,可以使用單個 Reverb 安裝來服務多個應用程式。
例如,您可能希望維護單個 Laravel 應用程式,該應用程式通過 Reverb 為多個應用程式提供 WebSocket 連線能力。這可以通過在應用程式的 config/reverb.php
配置檔案中定義多個 apps
來實現
1'apps' => [ 2 [ 3 'app_id' => 'my-app-one', 4 // ... 5 ], 6 [ 7 'app_id' => 'my-app-two', 8 // ... 9 ],10],
SSL
在大多數情況下,安全的 WebSocket 連線由上游 Web 伺服器(Nginx 等)處理,然後請求被代理到您的 Reverb 伺服器。
但是,有時 Reverb 伺服器直接處理安全連線可能很有用,例如在本地開發期間。如果您正在使用 Laravel Herd 的 安全站點功能,或者您正在使用 Laravel Valet 並且已針對您的應用程式運行 secure 命令,則可以使用為您的站點生成的 Herd / Valet 憑證來保護您的 Reverb 連線。為此,請將 REVERB_HOST
環境變數設定為您站點的主機名稱,或在啟動 Reverb 伺服器時顯式傳遞主機名稱選項
1php 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 上下文選項 支援的任何選項
1'options' => [2 'tls' => [3 'local_cert' => '/path/to/cert.pem'4 ],5],
執行伺服器
可以使用 reverb:start
Artisan 命令啟動 Reverb 伺服器
1php artisan reverb:start
預設情況下,Reverb 伺服器將在 0.0.0.0:8080
啟動,使其可從所有網路介面訪問。
如果您需要指定自訂主機或端口,您可以在啟動伺服器時通過 --host
和 --port
選項來完成
1php 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 將廣播訊息發送到哪裡。例如,在生產環境中,您可以將來自端口 443
上公共 Reverb 主機名稱的請求路由到在 0.0.0.0:8080
上運行的 Reverb 伺服器。在這種情況下,您的環境變數將定義如下
1REVERB_SERVER_HOST=0.0.0.02REVERB_SERVER_PORT=80803 4REVERB_HOST=ws.laravel.com5REVERB_PORT=443
偵錯
為了提高效能,Reverb 預設不輸出任何偵錯資訊。如果您想查看通過 Reverb 伺服器的數據流,您可以為 reverb:start
命令提供 --debug
選項
1php artisan reverb:start --debug
重新啟動
由於 Reverb 是一個長時間運行的程序,因此如果不通過 reverb:restart
Artisan 命令重新啟動伺服器,對程式碼的更改將不會反映出來。
reverb:restart
命令確保在停止伺服器之前優雅地終止所有連線。如果您正在使用諸如 Supervisor 之類的程序管理器運行 Reverb,則在終止所有連線後,伺服器將由程序管理器自動重新啟動
1php artisan reverb:restart
監控
Reverb 可以通過與 Laravel Pulse 的整合進行監控。通過啟用 Reverb 的 Pulse 整合,您可以追蹤伺服器正在處理的連線數和訊息數。
要啟用整合,您應該首先確保您已 安裝 Pulse。然後,將任何 Reverb 的記錄器添加到應用程式的 config/pulse.php
配置檔案中
1use Laravel\Reverb\Pulse\Recorders\ReverbConnections; 2use Laravel\Reverb\Pulse\Recorders\ReverbMessages; 3 4'recorders' => [ 5 ReverbConnections::class => [ 6 'sample_rate' => 1, 7 ], 8 9 ReverbMessages::class => [10 'sample_rate' => 1,11 ],12 13 // ...14],
接下來,將每個記錄器的 Pulse 卡片添加到您的 Pulse 儀表板
1<x-pulse>2 <livewire:reverb.connections cols="full" />3 <livewire:reverb.messages cols="full" />4 ...5</x-pulse>
連線活動通過定期輪詢新更新來記錄。為了確保此資訊在 Pulse 儀表板上正確呈現,您必須在 Reverb 伺服器上運行 pulse:check
常駐程序。如果您在 水平擴展 配置中運行 Reverb,則您應該僅在其中一個伺服器上運行此常駐程序。
在生產環境中執行 Reverb
由於 WebSocket 伺服器的長時間運行性質,您可能需要對伺服器和託管環境進行一些最佳化,以確保 Reverb 伺服器可以有效地處理伺服器上可用資源的最佳連線數。
如果您的站點由 Laravel Forge 管理,您可以直接從「應用程式」面板自動最佳化您的伺服器以用於 Reverb。通過啟用 Reverb 整合,Forge 將確保您的伺服器已準備好生產環境,包括安裝任何必需的擴展並增加允許的連線數。
開啟檔案
每個 WebSocket 連線都保存在記憶體中,直到客戶端或伺服器斷開連線。在 Unix 和類 Unix 環境中,每個連線都由一個檔案表示。但是,在作業系統和應用程式級別上,通常都對允許的開啟檔案數有限制。
作業系統
在基於 Unix 的作業系統上,您可以使用 ulimit
命令確定允許的開啟檔案數
1ulimit -n
此命令將顯示為不同用戶允許的開啟檔案限制。您可以通過編輯 /etc/security/limits.conf
檔案來更新這些值。例如,將 forge
用戶的最大開啟檔案數更新為 10,000 將如下所示
1# /etc/security/limits.conf2forge soft nofile 100003forge hard nofile 10000
事件迴圈
在底層,Reverb 使用 ReactPHP 事件迴圈來管理伺服器上的 WebSocket 連線。預設情況下,此事件迴圈由 stream_select
提供支持,後者不需要任何額外的擴展。但是,stream_select
通常限制為 1,024 個開啟檔案。因此,如果您計劃處理超過 1,000 個並行連線,則需要使用不受相同限制約束的替代事件迴圈。
Reverb 將在 ext-uv
支援的迴圈可用時自動切換到該迴圈。此 PHP 擴展可通過 PECL 安裝
1pecl install uv
Web 伺服器
在大多數情況下,Reverb 在伺服器上的非面向 Web 的端口上運行。因此,為了將流量路由到 Reverb,您應該配置反向代理。假設 Reverb 在主機 0.0.0.0
和端口 8080
上運行,並且您的伺服器使用 Nginx Web 伺服器,則可以使用以下 Nginx 站點配置為您的 Reverb 伺服器定義反向代理
1server { 2 ... 3 4 location / { 5 proxy_http_version 1.1; 6 proxy_set_header Host $http_host; 7 proxy_set_header Scheme $scheme; 8 proxy_set_header SERVER_PORT $server_port; 9 proxy_set_header REMOTE_ADDR $remote_addr;10 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;11 proxy_set_header Upgrade $http_upgrade;12 proxy_set_header Connection "Upgrade";13 14 proxy_pass http://0.0.0.0:8080;15 }16 17 ...18}
Reverb 監聽 /app
上的 WebSocket 連線並處理 /apps
上的 API 請求。您應該確保處理 Reverb 請求的 Web 伺服器可以服務這兩個 URI。如果您正在使用 Laravel Forge 來管理您的伺服器,則您的 Reverb 伺服器將預設情況下正確配置。
通常,Web 伺服器配置為限制允許的連線數,以防止伺服器過載。要將 Nginx Web 伺服器上允許的連線數增加到 10,000,應更新 nginx.conf
檔案的 worker_rlimit_nofile
和 worker_connections
值
1user forge; 2worker_processes auto; 3pid /run/nginx.pid; 4include /etc/nginx/modules-enabled/*.conf; 5worker_rlimit_nofile 10000; 6 7events { 8 worker_connections 10000; 9 multi_accept on;10}
上面的配置將允許每個進程最多產生 10,000 個 Nginx 工作進程。此外,此配置將 Nginx 的開啟檔案限制設定為 10,000。
端口
基於 Unix 的作業系統通常限制可以在伺服器上開啟的端口數。您可以通過以下命令查看當前允許的範圍
1cat /proc/sys/net/ipv4/ip_local_port_range2# 32768 60999
上面的輸出顯示伺服器最多可以處理 28,231 個連線 (60,999 - 32,768),因為每個連線都需要一個空閒端口。雖然我們建議 水平擴展 以增加允許的連線數,但您可以通過更新伺服器的 /etc/sysctl.conf
配置檔案中允許的端口範圍來增加可用的開啟端口數。
程序管理
在大多數情況下,您應該使用諸如 Supervisor 之類的程序管理器,以確保 Reverb 伺服器持續運行。如果您正在使用 Supervisor 運行 Reverb,則應更新伺服器的 supervisor.conf
檔案的 minfds
設定,以確保 Supervisor 能夠開啟處理與 Reverb 伺服器的連線所需的檔案
1[supervisord]2...3minfds=10000
擴展
如果您需要處理的連線多於單個伺服器所允許的連線,則可以水平擴展 Reverb 伺服器。利用 Redis 的發布/訂閱功能,Reverb 能夠跨多個伺服器管理連線。當其中一個應用程式的 Reverb 伺服器收到訊息時,伺服器將使用 Redis 將傳入的訊息發布到所有其他伺服器。
要啟用水平擴展,您應該在應用程式的 .env
配置檔案中將 REVERB_SCALING_ENABLED
環境變數設定為 true
1REVERB_SCALING_ENABLED=true
接下來,您應該有一個專用的中央 Redis 伺服器,所有 Reverb 伺服器都將與之通信。Reverb 將使用為您的應用程式配置的 預設 Redis 連線,以將訊息發布到所有 Reverb 伺服器。
一旦您啟用了 Reverb 的擴展選項並配置了 Redis 伺服器,您只需在能夠與 Redis 伺服器通信的多個伺服器上調用 reverb:start
命令即可。這些 Reverb 伺服器應放置在負載平衡器之後,該負載平衡器將傳入的請求均勻地分配到伺服器之間。