メインコンテンツまでスキップ

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

許可されたオリジン

config/reverb.php 設定ファイルの apps セクション内の allowed_origins 設定値を更新することで、クライアントリクエストの元となるオリジンを定義することもできます。許可されたオリジンにリストされていないオリジンからのリクエストは拒否されます。* を使用してすべてのオリジンを許可することもできます。

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

追加アプリケーション

通常、Reverbはインストールされたアプリケーション用にWebSocketサーバーを提供します。ただし、1つのReverbインストールを使用して複数のアプリケーションを提供することも可能です。

たとえば、Reverbを介して複数のアプリケーションに対するWebSocket接続を提供する単一のLaravelアプリケーションを維持したい場合、アプリケーションのconfig/reverb.php構成ファイルで複数のappsを定義することで実現できます:

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

SSL

ほとんどの場合、セキュアなWebSocket接続は、リクエストがReverbサーバーにプロキシされる前に上流ウェブサーバー(Nginxなど)で処理されます。

ただし、ローカル開発中など、Reverbサーバーが直接セキュアな接続を処理することが便利な場合があります。Laravel Herdのセキュアサイト機能を使用しているか、Laravel Valetを使用しており、アプリケーションにsecureコマンドを実行している場合は、サイトのために生成されたHerd / Valet証明書を使用してReverb接続をセキュアにすることができます。これを行うには、REVERB_HOST環境変数をサイトのホスト名に設定するか、Reverbサーバーを起動する際にホスト名オプションを明示的に渡します:

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'
],
],

サーバーの起動

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でリクエストをReverbサーバーが0.0.0.0:8080で動作している場所にルーティングすることができます。このシナリオでは、環境変数は次のように定義されます:

REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080

REVERB_HOST=ws.laravel.com
REVERB_PORT=443

デバッグ

パフォーマンスを向上させるため、Reverbはデフォルトでデバッグ情報を出力しません。Reverbサーバーを通過するデータのストリームを表示したい場合は、reverb:startコマンドに--debugオプションを指定することができます:

php artisan reverb:start --debug

再起動

Reverbは長時間実行されるプロセスなので、コードの変更を反映させるにはreverb:restart Artisanコマンドを使用してサーバーを再起動する必要があります。

reverb:restartコマンドは、サーバーを停止する前にすべての接続を正常に終了させることを保証します。SupervisorなどのプロセスマネージャでReverbを実行している場合、すべての接続が終了した後にプロセスマネージャによってサーバーが自動的に再起動されます:

php artisan reverb:restart

モニタリング

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>

本番環境でのReverbの実行

WebSocketサーバーの長時間稼働の性質から、Reverbサーバーがリソースに適切に対応できるように、サーバーとホスティング環境にいくつかの最適化を行う必要がある場合があります。

注記

もしLaravel Forgeでサイトを管理している場合、"Application"パネルから直接Reverb用にサーバーを最適化することができます。Reverb統合を有効にすると、Forgeが必要な拡張機能をインストールし、許可される接続数を増やすなど、サーバーを本番環境に適した状態にします。

オープンファイル

各WebSocket接続は、クライアントまたはサーバーが切断されるまでメモリに保持されます。UnixおよびUnix系環境では、各接続はファイルで表されます。ただし、オペレーティングシステムおよびアプリケーションレベルの許可されるオープンファイル数には制限があることがよくあります。

オペレーティングシステム

Unixベースのオペレーティングシステムでは、ulimitコマンドを使用して許可されるオープンファイル数を確認できます:

ulimit -n

このコマンドは、異なるユーザーに許可されるオープンファイルの制限を表示します。forgeユーザーの最大オープンファイル数を例えば10,000に更新する場合、次のように/etc/security/limits.confファイルを編集します:

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

イベントループ

Reverbはサーバー上でWebSocket接続を管理するためにReactPHPイベントループを使用しています。デフォルトでは、このイベントループはstream_selectによって動作しており、追加の拡張機能は必要ありません。ただし、stream_selectは通常1,024個のオープンファイルに制限されています。したがって、1,000以上の同時接続を処理する予定がある場合は、同じ制限に制約されない代替イベントループを使用する必要があります。

Reverbは、利用可能な場合には自動的にext-uvパワードループに切り替わります。このPHP拡張機能はPECLを介してインストールできます:

pecl install uv

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;
}

...
}

通常、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;
}

上記の構成により、1プロセスあたり最大10,000のNginxワーカーが生成されるようになります。さらに、この構成では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

ほとんどの場合、Reverbサーバーが継続的に実行されるようにするためには、Supervisorなどのプロセスマネージャーを使用する必要があります。Reverbを実行するためにSupervisorを使用している場合は、サーバーのsupervisor.confファイルのminfds設定を更新して、SupervisorがReverbサーバーへの接続を処理するために必要なファイルを開くことができるようにする必要があります:

[supervisord]
...
minfds=10000

Scaling

単一のサーバーで許可される接続数を超える必要がある場合は、Reverbサーバーを水平にスケーリングすることができます。Redisのパブリッシュ/サブスクライブ機能を利用して、Reverbは複数のサーバー間で接続を管理することができます。アプリケーションのReverbサーバーの1つがメッセージを受信すると、サーバーはRedisを使用して受信したメッセージを他のすべてのサーバーに公開します。

水平スケーリングを有効にするには、アプリケーションの.env構成ファイルでREVERB_SCALING_ENABLED環境変数をtrueに設定する必要があります:

REVERB_SCALING_ENABLED=true

次に、すべてのReverbサーバーが通信する専用の中央Redisサーバーを用意する必要があります。Reverbは、アプリケーションに構成されたデフォルトのRedis接続を使用して、すべてのReverbサーバーにメッセージを公開します。

Reverbのスケーリングオプションを有効にし、Redisサーバーを構成した後は、Redisサーバーと通信できる複数のサーバーでreverb:startコマンドを単純に呼び出すだけでよくなります。これらのReverbサーバーは、受信リクエストを均等に分散するロードバランサーの背後に配置する必要があります。