Init
This commit is contained in:
625
output/12.x/reverb.md
Normal file
625
output/12.x/reverb.md
Normal file
@@ -0,0 +1,625 @@
|
||||
# Laravel Reverb
|
||||
|
||||
* Introduction
|
||||
* Installation
|
||||
* Configuration
|
||||
* Application Credentials
|
||||
* Allowed Origins
|
||||
* Additional Applications
|
||||
* SSL
|
||||
* Running the Server
|
||||
* Debugging
|
||||
* Restarting
|
||||
* Monitoring
|
||||
* Running Reverb in Production
|
||||
* Open Files
|
||||
* Event Loop
|
||||
* Web Server
|
||||
* Ports
|
||||
* Process Management
|
||||
* Scaling
|
||||
|
||||
## Introduction
|
||||
|
||||
[Laravel Reverb](https://github.com/laravel/reverb) brings blazing-fast and
|
||||
scalable real-time WebSocket communication directly to your Laravel
|
||||
application, and provides seamless integration with Laravel's existing suite
|
||||
of [event broadcasting tools](/docs/12.x/broadcasting).
|
||||
|
||||
## Installation
|
||||
|
||||
You may install Reverb using the `install:broadcasting` Artisan command:
|
||||
|
||||
|
||||
|
||||
1php artisan install:broadcasting
|
||||
|
||||
|
||||
php artisan install:broadcasting
|
||||
|
||||
## Configuration
|
||||
|
||||
Behind the scenes, the `install:broadcasting` Artisan command will run the
|
||||
`reverb:install` command, which will install Reverb with a sensible set of
|
||||
default configuration options. If you would like to make any configuration
|
||||
changes, you may do so by updating Reverb's environment variables or by
|
||||
updating the `config/reverb.php` configuration file.
|
||||
|
||||
### Application Credentials
|
||||
|
||||
In order to establish a connection to Reverb, a set of Reverb "application"
|
||||
credentials must be exchanged between the client and server. These credentials
|
||||
are configured on the server and are used to verify the request from the
|
||||
client. You may define these credentials using the following environment
|
||||
variables:
|
||||
|
||||
|
||||
|
||||
1REVERB_APP_ID=my-app-id
|
||||
|
||||
2REVERB_APP_KEY=my-app-key
|
||||
|
||||
3REVERB_APP_SECRET=my-app-secret
|
||||
|
||||
|
||||
REVERB_APP_ID=my-app-id
|
||||
REVERB_APP_KEY=my-app-key
|
||||
REVERB_APP_SECRET=my-app-secret
|
||||
|
||||
### Allowed Origins
|
||||
|
||||
You may also define the origins from which client requests may originate by
|
||||
updating the value of the `allowed_origins` configuration value within the
|
||||
`apps` section of the `config/reverb.php` configuration file. Any requests
|
||||
from an origin not listed in your allowed origins will be rejected. You may
|
||||
allow all origins using `*`:
|
||||
|
||||
|
||||
|
||||
1'apps' => [
|
||||
|
||||
2 [
|
||||
|
||||
3 'app_id' => 'my-app-id',
|
||||
|
||||
4 'allowed_origins' => ['laravel.com'],
|
||||
|
||||
5 // ...
|
||||
|
||||
6 ]
|
||||
|
||||
7]
|
||||
|
||||
|
||||
'apps' => [
|
||||
[
|
||||
'app_id' => 'my-app-id',
|
||||
'allowed_origins' => ['laravel.com'],
|
||||
// ...
|
||||
]
|
||||
]
|
||||
|
||||
### Additional Applications
|
||||
|
||||
Typically, Reverb provides a WebSocket server for the application in which it
|
||||
is installed. However, it is possible to serve more than one application using
|
||||
a single Reverb installation.
|
||||
|
||||
For example, you may wish to maintain a single Laravel application which, via
|
||||
Reverb, provides WebSocket connectivity for multiple applications. This can be
|
||||
achieved by defining multiple `apps` in your application's `config/reverb.php`
|
||||
configuration file:
|
||||
|
||||
|
||||
|
||||
1'apps' => [
|
||||
|
||||
2 [
|
||||
|
||||
3 'app_id' => 'my-app-one',
|
||||
|
||||
4 // ...
|
||||
|
||||
5 ],
|
||||
|
||||
6 [
|
||||
|
||||
7 'app_id' => 'my-app-two',
|
||||
|
||||
8 // ...
|
||||
|
||||
9 ],
|
||||
|
||||
10],
|
||||
|
||||
|
||||
'apps' => [
|
||||
[
|
||||
'app_id' => 'my-app-one',
|
||||
// ...
|
||||
],
|
||||
[
|
||||
'app_id' => 'my-app-two',
|
||||
// ...
|
||||
],
|
||||
],
|
||||
|
||||
### SSL
|
||||
|
||||
In most cases, secure WebSocket connections are handled by the upstream web
|
||||
server (Nginx, etc.) before the request is proxied to your Reverb server.
|
||||
|
||||
However, it can sometimes be useful, such as during local development, for the
|
||||
Reverb server to handle secure connections directly. If you are using [Laravel
|
||||
Herd's](https://herd.laravel.com) secure site feature or you are using
|
||||
[Laravel Valet](/docs/12.x/valet) and have run the [secure
|
||||
command](/docs/12.x/valet#securing-sites) against your application, you may
|
||||
use the Herd / Valet certificate generated for your site to secure your Reverb
|
||||
connections. To do so, set the `REVERB_HOST` environment variable to your
|
||||
site's hostname or explicitly pass the hostname option when starting the
|
||||
Reverb server:
|
||||
|
||||
|
||||
|
||||
1php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"
|
||||
|
||||
|
||||
php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"
|
||||
|
||||
Since Herd and Valet domains resolve to `localhost`, running the command above
|
||||
will result in your Reverb server being accessible via the secure WebSocket
|
||||
protocol (`wss`) at `wss://laravel.test:8080`.
|
||||
|
||||
You may also manually choose a certificate by defining `tls` options in your
|
||||
application's `config/reverb.php` configuration file. Within the array of
|
||||
`tls` options, you may provide any of the options supported by [PHP's SSL
|
||||
context options](https://www.php.net/manual/en/context.ssl.php):
|
||||
|
||||
|
||||
|
||||
1'options' => [
|
||||
|
||||
2 'tls' => [
|
||||
|
||||
3 'local_cert' => '/path/to/cert.pem'
|
||||
|
||||
4 ],
|
||||
|
||||
5],
|
||||
|
||||
|
||||
'options' => [
|
||||
'tls' => [
|
||||
'local_cert' => '/path/to/cert.pem'
|
||||
],
|
||||
],
|
||||
|
||||
## Running the Server
|
||||
|
||||
The Reverb server can be started using the `reverb:start` Artisan command:
|
||||
|
||||
|
||||
|
||||
1php artisan reverb:start
|
||||
|
||||
|
||||
php artisan reverb:start
|
||||
|
||||
By default, the Reverb server will be started at `0.0.0.0:8080`, making it
|
||||
accessible from all network interfaces.
|
||||
|
||||
If you need to specify a custom host or port, you may do so via the `--host`
|
||||
and `--port` options when starting the server:
|
||||
|
||||
|
||||
|
||||
1php artisan reverb:start --host=127.0.0.1 --port=9000
|
||||
|
||||
|
||||
php artisan reverb:start --host=127.0.0.1 --port=9000
|
||||
|
||||
Alternatively, you may define `REVERB_SERVER_HOST` and `REVERB_SERVER_PORT`
|
||||
environment variables in your application's `.env` configuration file.
|
||||
|
||||
The `REVERB_SERVER_HOST` and `REVERB_SERVER_PORT` environment variables should
|
||||
not be confused with `REVERB_HOST` and `REVERB_PORT`. The former specify the
|
||||
host and port on which to run the Reverb server itself, while the latter pair
|
||||
instruct Laravel where to send broadcast messages. For example, in a
|
||||
production environment, you may route requests from your public Reverb
|
||||
hostname on port `443` to a Reverb server operating on `0.0.0.0:8080`. In this
|
||||
scenario, your environment variables would be defined as follows:
|
||||
|
||||
|
||||
|
||||
1REVERB_SERVER_HOST=0.0.0.0
|
||||
|
||||
2REVERB_SERVER_PORT=8080
|
||||
|
||||
3
|
||||
|
||||
4REVERB_HOST=ws.laravel.com
|
||||
|
||||
5REVERB_PORT=443
|
||||
|
||||
|
||||
REVERB_SERVER_HOST=0.0.0.0
|
||||
REVERB_SERVER_PORT=8080
|
||||
|
||||
REVERB_HOST=ws.laravel.com
|
||||
REVERB_PORT=443
|
||||
|
||||
### Debugging
|
||||
|
||||
To improve performance, Reverb does not output any debug information by
|
||||
default. If you would like to see the stream of data passing through your
|
||||
Reverb server, you may provide the `--debug` option to the `reverb:start`
|
||||
command:
|
||||
|
||||
|
||||
|
||||
1php artisan reverb:start --debug
|
||||
|
||||
|
||||
php artisan reverb:start --debug
|
||||
|
||||
### Restarting
|
||||
|
||||
Since Reverb is a long-running process, changes to your code will not be
|
||||
reflected without restarting the server via the `reverb:restart` Artisan
|
||||
command.
|
||||
|
||||
The `reverb:restart` command ensures all connections are gracefully terminated
|
||||
before stopping the server. If you are running Reverb with a process manager
|
||||
such as Supervisor, the server will be automatically restarted by the process
|
||||
manager after all connections have been terminated:
|
||||
|
||||
|
||||
|
||||
1php artisan reverb:restart
|
||||
|
||||
|
||||
php artisan reverb:restart
|
||||
|
||||
## Monitoring
|
||||
|
||||
Reverb may be monitored via an integration with [Laravel
|
||||
Pulse](/docs/12.x/pulse). By enabling Reverb's Pulse integration, you may
|
||||
track the number of connections and messages being handled by your server.
|
||||
|
||||
To enable the integration, you should first ensure you have [installed
|
||||
Pulse](/docs/12.x/pulse#installation). Then, add any of Reverb's recorders to
|
||||
your application's `config/pulse.php` configuration file:
|
||||
|
||||
|
||||
|
||||
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],
|
||||
|
||||
|
||||
use Laravel\Reverb\Pulse\Recorders\ReverbConnections;
|
||||
use Laravel\Reverb\Pulse\Recorders\ReverbMessages;
|
||||
|
||||
'recorders' => [
|
||||
ReverbConnections::class => [
|
||||
'sample_rate' => 1,
|
||||
],
|
||||
|
||||
ReverbMessages::class => [
|
||||
'sample_rate' => 1,
|
||||
],
|
||||
|
||||
// ...
|
||||
],
|
||||
|
||||
Next, add the Pulse cards for each recorder to your [Pulse
|
||||
dashboard](/docs/12.x/pulse#dashboard-customization):
|
||||
|
||||
|
||||
|
||||
1<x-pulse>
|
||||
|
||||
2 <livewire:reverb.connections cols="full" />
|
||||
|
||||
3 <livewire:reverb.messages cols="full" />
|
||||
|
||||
4 ...
|
||||
|
||||
5</x-pulse>
|
||||
|
||||
|
||||
<x-pulse>
|
||||
<livewire:reverb.connections cols="full" />
|
||||
<livewire:reverb.messages cols="full" />
|
||||
...
|
||||
</x-pulse>
|
||||
|
||||
Connection activity is recorded by polling for new updates on a periodic
|
||||
basis. To ensure this information is rendered correctly on the Pulse
|
||||
dashboard, you must run the `pulse:check` daemon on your Reverb server. If you
|
||||
are running Reverb in a horizontally scaled configuration, you should only run
|
||||
this daemon on one of your servers.
|
||||
|
||||
## Running Reverb in Production
|
||||
|
||||
Due to the long-running nature of WebSocket servers, you may need to make some
|
||||
optimizations to your server and hosting environment to ensure your Reverb
|
||||
server can effectively handle the optimal number of connections for the
|
||||
resources available on your server.
|
||||
|
||||
If your site is managed by [Laravel Forge](https://forge.laravel.com), you may
|
||||
automatically optimize your server for Reverb directly from the "Application"
|
||||
panel. By enabling the Reverb integration, Forge will ensure your server is
|
||||
production-ready, including installing any required extensions and increasing
|
||||
the allowed number of connections.
|
||||
|
||||
### Open Files
|
||||
|
||||
Each WebSocket connection is held in memory until either the client or server
|
||||
disconnects. In Unix and Unix-like environments, each connection is
|
||||
represented by a file. However, there are often limits on the number of
|
||||
allowed open files at both the operating system and application level.
|
||||
|
||||
#### Operating System
|
||||
|
||||
On a Unix based operating system, you may determine the allowed number of open
|
||||
files using the `ulimit` command:
|
||||
|
||||
|
||||
|
||||
1ulimit -n
|
||||
|
||||
|
||||
ulimit -n
|
||||
|
||||
This command will display the open file limits allowed for different users.
|
||||
You may update these values by editing the `/etc/security/limits.conf` file.
|
||||
For example, updating the maximum number of open files to 10,000 for the
|
||||
`forge` user would look like the following:
|
||||
|
||||
|
||||
|
||||
1# /etc/security/limits.conf
|
||||
|
||||
2forge soft nofile 10000
|
||||
|
||||
3forge hard nofile 10000
|
||||
|
||||
|
||||
# /etc/security/limits.conf
|
||||
forge soft nofile 10000
|
||||
forge hard nofile 10000
|
||||
|
||||
### Event Loop
|
||||
|
||||
Under the hood, Reverb uses a ReactPHP event loop to manage WebSocket
|
||||
connections on the server. By default, this event loop is powered by
|
||||
`stream_select`, which doesn't require any additional extensions. However,
|
||||
`stream_select` is typically limited to 1,024 open files. As such, if you plan
|
||||
to handle more than 1,000 concurrent connections, you will need to use an
|
||||
alternative event loop not bound to the same restrictions.
|
||||
|
||||
Reverb will automatically switch to an `ext-uv` powered loop when available.
|
||||
This PHP extension is available for install via PECL:
|
||||
|
||||
|
||||
|
||||
1pecl install uv
|
||||
|
||||
|
||||
pecl install uv
|
||||
|
||||
### Web Server
|
||||
|
||||
In most cases, Reverb runs on a non web-facing port on your server. So, in
|
||||
order to route traffic to Reverb, you should configure a reverse proxy.
|
||||
Assuming Reverb is running on host `0.0.0.0` and port `8080` and your server
|
||||
utilizes the Nginx web server, a reverse proxy can be defined for your Reverb
|
||||
server using the following Nginx site configuration:
|
||||
|
||||
|
||||
|
||||
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}
|
||||
|
||||
|
||||
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 listens for WebSocket connections at `/app` and handles API requests at
|
||||
`/apps`. You should ensure the web server handling Reverb requests can serve
|
||||
both of these URIs. If you are using [Laravel
|
||||
Forge](https://forge.laravel.com) to manage your servers, your Reverb server
|
||||
will be correctly configured by default.
|
||||
|
||||
Typically, web servers are configured to limit the number of allowed
|
||||
connections in order to prevent overloading the server. To increase the number
|
||||
of allowed connections on an Nginx web server to 10,000, the
|
||||
`worker_rlimit_nofile` and `worker_connections` values of the `nginx.conf`
|
||||
file should be updated:
|
||||
|
||||
|
||||
|
||||
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}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
The configuration above will allow up to 10,000 Nginx workers per process to
|
||||
be spawned. In addition, this configuration sets Nginx's open file limit to
|
||||
10,000.
|
||||
|
||||
### Ports
|
||||
|
||||
Unix-based operating systems typically limit the number of ports which can be
|
||||
opened on the server. You may see the current allowed range via the following
|
||||
command:
|
||||
|
||||
|
||||
|
||||
1cat /proc/sys/net/ipv4/ip_local_port_range
|
||||
|
||||
2# 32768 60999
|
||||
|
||||
|
||||
cat /proc/sys/net/ipv4/ip_local_port_range
|
||||
# 32768 60999
|
||||
|
||||
The output above shows the server can handle a maximum of 28,231 (60,999 -
|
||||
32,768) connections since each connection requires a free port. Although we
|
||||
recommend horizontal scaling to increase the number of allowed connections,
|
||||
you may increase the number of available open ports by updating the allowed
|
||||
port range in your server's `/etc/sysctl.conf` configuration file.
|
||||
|
||||
### Process Management
|
||||
|
||||
In most cases, you should use a process manager such as Supervisor to ensure
|
||||
the Reverb server is continually running. If you are using Supervisor to run
|
||||
Reverb, you should update the `minfds` setting of your server's
|
||||
`supervisor.conf` file to ensure Supervisor is able to open the files required
|
||||
to handle connections to your Reverb server:
|
||||
|
||||
|
||||
|
||||
1[supervisord]
|
||||
|
||||
2...
|
||||
|
||||
3minfds=10000
|
||||
|
||||
|
||||
[supervisord]
|
||||
...
|
||||
minfds=10000
|
||||
|
||||
### Scaling
|
||||
|
||||
If you need to handle more connections than a single server will allow, you
|
||||
may scale your Reverb server horizontally. Utilizing the publish / subscribe
|
||||
capabilities of Redis, Reverb is able to manage connections across multiple
|
||||
servers. When a message is received by one of your application's Reverb
|
||||
servers, the server will use Redis to publish the incoming message to all
|
||||
other servers.
|
||||
|
||||
To enable horizontal scaling, you should set the `REVERB_SCALING_ENABLED`
|
||||
environment variable to `true` in your application's `.env` configuration
|
||||
file:
|
||||
|
||||
|
||||
|
||||
1REVERB_SCALING_ENABLED=true
|
||||
|
||||
|
||||
REVERB_SCALING_ENABLED=true
|
||||
|
||||
Next, you should have a dedicated, central Redis server to which all of the
|
||||
Reverb servers will communicate. Reverb will use the [default Redis connection
|
||||
configured for your application](/docs/12.x/redis#configuration) to publish
|
||||
messages to all of your Reverb servers.
|
||||
|
||||
Once you have enabled Reverb's scaling option and configured a Redis server,
|
||||
you may simply invoke the `reverb:start` command on multiple servers that are
|
||||
able to communicate with your Redis server. These Reverb servers should be
|
||||
placed behind a load balancer that distributes incoming requests evenly among
|
||||
the servers.
|
||||
|
||||
Reference in New Issue
Block a user