Reverb

Introduzione

Laravel Reverb porta una comunicazione WebSocket in tempo reale molto veloce e scalabile direttamente nella tua applicazione Laravel e offre un’integrazione perfetta con la suite esistente di strumenti di event broadcasting di Laravel.

Installazione

Puoi installare Reverb utilizzando il comando Artisan install:broadcasting:

php artisan install:broadcasting

Configurazione

Il comando install:broadcasting di Artisan esegue in background il comando reverb:install, che installa Reverb con una serie di opzioni di configurazione predefinite. Se vuoi modificare qualche configurazione, puoi aggiornare le variabili d’ambiente di Reverb o modificare il file di configurazione config/reverb.php.

Credenziali dell’Applicazione

Per stabilire una connessione a Reverb, è necessario scambiare un set di credenziali "application" di Reverb tra client e server. Queste credenziali sono configurate sul server e vengono utilizzate per verificare le richieste dal client. Puoi definire queste credenziali utilizzando le seguenti variabili di ambiente:

REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret

Origini Consentite

Puoi anche definire le origini da cui possono provenire le richieste dei client aggiornando il valore di allowed_origins nella sezione apps del file di configurazione config/reverb.php. Qualsiasi richiesta proveniente da un’origine non elencata tra le tue origini consentite sarà rifiutata. Puoi consentire tutte le origini usando *:

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

Applicazioni Aggiuntive

Di solito, Reverb fornisce un server WebSocket per l’applicazione in cui è installato. Tuttavia, è possibile supportare più applicazioni utilizzando una singola installazione di Reverb.

Ad esempio, potresti voler mantenere un’unica applicazione Laravel che, tramite Reverb, fornisce connettività WebSocket per diverse applicazioni. Questo può essere fatto definendo più apps nel file di configurazione config/reverb.php della tua applicazione:

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

SSL

Nella maggior parte dei casi, le connessioni WebSocket sicure vengono gestite dal server web upstream (Nginx, ecc.) prima che la richiesta venga inoltrata al tuo server Reverb.

Tuttavia, a volte può essere utile, ad esempio durante lo sviluppo locale, che il server Reverb gestisca direttamente le connessioni sicure. Se stai utilizzando la funzionalità di sito sicuro di Laravel Herd’s o Laravel Valet e hai eseguito il comando secure sulla tua applicazione, puoi utilizzare il certificato Herd / Valet generato per il tuo sito per proteggere le connessioni Reverb. Per farlo, imposta la variabile d’ambiente REVERB_HOST sul nome host del tuo sito oppure passa esplicitamente l’opzione hostname quando avvii il server Reverb:

php artisan reverb:start --host="0.0.0.0" --port=8080 --hostname="laravel.test"

Poiché i domini Herd e Valet risolvono in localhost, eseguendo il comando sopra il tuo server Reverb sarà accessibile tramite il protocollo WebSocket sicuro (wss) a wss://laravel.test:8080.

Puoi anche scegliere manualmente un certificato definendo le opzioni tls nel file di configurazione config/reverb.php della tua applicazione. All’interno dell’array delle opzioni tls, puoi fornire qualsiasi opzione supportata da PHP’s SSL context options:

'options' => [
    'tls' => [
        'local_cert' => '/path/to/cert.pem'
    ],
],

Eseguire il Server

Il server Reverb può essere avviato utilizzando il comando Artisan reverb:start:

php artisan reverb:start

Per impostazione predefinita, il server Reverb verrà avviato su 0.0.0.0:8080, rendendolo accessibile da tutte le interfacce di rete.

Se hai bisogno di specificare un host o una porta personalizzati, puoi farlo tramite le opzioni --host e --port quando avvii il server:

php artisan reverb:start --host=127.0.0.1 --port=9000

In alternativa, puoi definire le variabili d’ambiente REVERB_SERVER_HOST e REVERB_SERVER_PORT nel file di configurazione .env della tua applicazione.

Le variabili d’ambiente REVERB_SERVER_HOST e REVERB_SERVER_PORT non devono essere confuse con REVERB_HOST e REVERB_PORT. Le prime specificano l’host e la porta su cui eseguire il server Reverb stesso, mentre il secondo gruppo istruisce Laravel su dove inviare i messaggi broadcast. Ad esempio, in un ambiente di produzione, potresti instradare le richieste dal tuo hostname pubblico Reverb sulla porta 443 verso un server Reverb operativo su 0.0.0.0:8080. In questo scenario, le tue variabili d’ambiente sarebbero definite come segue:

REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=8080

REVERB_HOST=ws.laravel.com
REVERB_PORT=443

Debugging

Per migliorare le prestazioni, Reverb non mostra informazioni di debug per impostazione predefinita. Se desideri visualizzare il flusso di dati che passa attraverso il tuo server Reverb, puoi usare l’opzione --debug nel comando reverb:start:

php artisan reverb:start --debug

Riavvio

Poiché Reverb è un processo che funziona a lungo, le modifiche al codice non saranno visibili senza riavviare il server usando il comando Artisan reverb:restart.

Il comando reverb:restart termina tutte le connessioni in modo corretto prima di fermare il server. Se utilizzi Reverb con un gestore di processi come Supervisor, il server verrà automaticamente riavviato dal gestore una volta terminate tutte le connessioni:

php artisan reverb:restart

Monitoraggio

Reverb può essere monitorato tramite un’integrazione con Laravel Pulse. Abilitando l’integrazione di Pulse per Reverb, puoi tenere traccia del numero di connessioni e messaggi gestiti dal tuo server.

Per abilitare l’integrazione, devi prima assicurarti di aver installato Pulse. Poi, aggiungi uno dei recorder di Reverb al file di configurazione config/pulse.php della tua applicazione:

use Laravel\Reverb\Pulse\Recorders\ReverbConnections;
use Laravel\Reverb\Pulse\Recorders\ReverbMessages;

'recorders' => [
    ReverbConnections::class => [
        'sample_rate' => 1,
    ],

    ReverbMessages::class => [
        'sample_rate' => 1,
    ],

    ...
],

Successivamente, aggiungi le card di Pulse per ogni recorder al tuo dashboard di Pulse:

<x-pulse>
    <livewire:reverb.connections cols="full" />
    <livewire:reverb.messages cols="full" />
    ...
</x-pulse>

L’attività delle connessioni viene registrata tramite polling periodico per nuovi aggiornamenti. Per assicurarti che queste informazioni siano visualizzate correttamente nella dashboard di Pulse, devi eseguire il daemon pulse:check sul tuo server Reverb. Se stai eseguendo Reverb in una configurazione orizzontale, dovresti eseguire questo daemon solo su uno dei tuoi server.

Eseguire Reverb in Produzione

A causa della natura a lunga esecuzione dei server WebSocket, potrebbe essere necessario ottimizzare il tuo server e l’ambiente di hosting per garantire che il server Reverb possa gestire efficacemente il numero ottimale di connessioni in base alle risorse disponibili sul tuo server.

Se il tuo sito è gestito da Laravel Forge, puoi ottimizzare automaticamente il tuo server per Reverb direttamente dal pannello "Applicazione". Abilitando l’integrazione Reverb, Forge garantirà che il tuo server sia pronto per la produzione, includendo l’installazione delle estensioni necessarie e aumentando il numero di connessioni consentite.

File Aperti

Ogni connessione WebSocket rimane in memoria finché il client o il server non si disconnettono. In ambienti Unix e simili a Unix, ogni connessione è rappresentata da un file. Tuttavia, spesso ci sono limiti sul numero di file aperti consentiti sia a livello del sistema operativo che dell’applicazione.

Sistema Operativo

Su un sistema operativo basato su Unix, puoi determinare il numero consentito di file aperti utilizzando il comando ulimit:

ulimit -n

Questo comando mostrerà i limiti dei file aperti consentiti per diversi utenti. Puoi aggiornare questi valori modificando il file /etc/security/limits.conf. Ad esempio, aggiornare il numero massimo di file aperti a 10.000 per l’utente forge apparirebbe come segue:

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

Ciclo degli Eventi

Sotto il cofano, Reverb utilizza un ciclo degli eventi di ReactPHP per gestire le connessioni WebSocket sul server. Per impostazione predefinita, questo ciclo degli eventi è alimentato da stream_select, che non richiede estensioni aggiuntive. Tuttavia, stream_select è solitamente limitato a 1.024 file aperti. Pertanto, se prevedi di gestire più di 1.000 connessioni concorrenti, dovrai usare un ciclo degli eventi alternativo non soggetto alle stesse restrizioni.

Reverb passerà automaticamente a un ciclo alimentato da ext-uv quando disponibile. Questa estensione PHP è disponibile per l’installazione tramite PECL:

pecl install uv

Web Server

Nella maggior parte dei casi, Reverb funziona su una porta non esposta al web sul tuo server. Pertanto, per indirizzare il traffico verso Reverb, devi configurare un reverse proxy. Supponendo che Reverb stia funzionando sull’host 0.0.0.0 e la porta 8080 e che il tuo server utilizzi il web server Nginx, puoi definire un reverse proxy per il tuo server Reverb utilizzando la seguente configurazione del sito 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 ascolta le connessioni WebSocket su /app e gestisce le richieste API su /apps. Assicurati che il web server che gestisce le richieste di Reverb possa servire entrambe queste URI. Se utilizzi Laravel Forge per gestire i tuoi server, il tuo server Reverb sarà configurato correttamente di default.

Tipicamente, i web server sono configurati per limitare il numero di connessioni consentite per evitare il sovraccarico del server. Per aumentare il numero di connessioni consentite su un web server Nginx a 10.000, i valori worker_rlimit_nofile e worker_connections del file nginx.conf dovrebbero essere aggiornati:

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

La configurazione sopra consentirà fino a 10.000 worker di Nginx per processo. Inoltre, questa configurazione imposta il limite di file aperti di Nginx a 10.000.

Porte

I sistemi operativi basati su Unix tipicamente limitano il numero di porte che possono essere aperte sul server. Puoi vedere l’intervallo attualmente consentito con il seguente comando:

cat /proc/sys/net/ipv4/ip_local_port_range
# 32768	60999

L’output sopra mostra che il server può gestire un massimo di 28.231 (60.999 – 32.768) connessioni poiché ogni connessione richiede una porta libera. Anche se consigliamo la scalabilità orizzontale per aumentare il numero di connessioni consentite, puoi aumentare il numero di porte aperte disponibili aggiornando l’intervallo di porte consentite nel file di configurazione /etc/sysctl.conf del tuo server.

Gestione dei Processi

In generale, dovresti utilizzare un process manager come Supervisor per garantire che il server Reverb sia sempre in esecuzione. Se usi Supervisor per eseguire Reverb, aggiorna l’impostazione minfds nel file supervisor.conf del tuo server per permettere a Supervisor di aprire i file necessari per gestire le connessioni al server Reverb:

[supervisord]
...
minfds=10000

Scalabilità

Se hai bisogno di gestire più connessioni di quanto un singolo server possa permettere, puoi scalare orizzontalmente il tuo server Reverb. Utilizzando le capacità di publish/subscriber di Redis, Reverb è in grado di gestire connessioni su più server. Quando un messaggio viene ricevuto da uno dei server Reverb della tua applicazione, il server utilizzerà Redis per pubblicare il messaggio in arrivo su tutti gli altri server.

Per abilitare la scalabilità orizzontale, dovresti impostare la variabile d’ambiente REVERB_SCALING_ENABLED su true nel file di configurazione .env della tua applicazione:

REVERB_SCALING_ENABLED=true

Successivamente, dovresti avere un server Redis centrale dedicato al quale tutti i server Reverb comunicheranno. Reverb utilizzerà la connessione Redis predefinita configurata per la tua applicazione per pubblicare i messaggi a tutti i tuoi server Reverb.

Una volta abilitata l’opzione di scalabilità di Reverb e configurato un server Redis, puoi semplicemente eseguire il comando reverb:start su più server in grado di comunicare con il tuo server Redis. Questi server Reverb dovrebbero essere posizionati dietro un bilanciatore di carico che distribuisce equamente le richieste in arrivo tra i server.

Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *