boot() può essere sovrascritto se il routes/channels.php dell’applicazione usa lo stesso nome. Comprendere questo ordine di registrazione e di valutazione aiuta a ridurre i bug durante la manutenzione.
Questa pagina fa riferimento alla documentazione ufficiale di Laravel sul broadcasting e all’implementazione dell’ultima release v13.42.0, usata per la verifica. Per l’invio degli eventi consulta broadcasting, per il caricamento dei provider consulta auto-discovery dei pacchetti.
Come funziona l’autorizzazione dei canali
Quando un client si iscrive a un canale privato, invia una richiesta a/broadcasting/auth. BroadcastController::authenticate() passa l’elaborazione a Broadcast::auth(), e il Broadcaster valuta in ordine le callback registrate.
Le regole di valutazione sono le seguenti:
- Se una callback restituisce
false, viene lanciata subito unaAccessDeniedHttpException. - Se restituisce un valore vero come
true, l’autorizzazione viene concessa in quel momento. - Se restituisce un valore falso come
null, si passa alla callback registrata successiva. Se nessuna concede l’accesso, alla fine viene lanciata unaAccessDeniedHttpException.
I driver
Pusher e Reverb rimuovono i prefissi private- e presence- prima dell’autorizzazione. Per questo non includere il prefisso nei nomi dei canali che registri.Registrare un canale nel pacchetto
Come esempio, un pacchetto fittizioAcme\Orders trasmette i cambi di stato degli ordini. Il nome del canale è acme.orders.{order} e solo il proprietario dell’ordine può iscriversi.
Nel ServiceProvider del pacchetto, chiama Broadcast::channel() all’interno di boot(). Delega la verifica a una classe del pacchetto.
join() riceve l’utente al momento dell’autorizzazione. Gli argomenti successivi ricevono i valori dei {...} nel nome del canale. Se il nome del parametro {order} corrisponde a Order $order e il tipo è una sottoclasse di UrlRoutable, si applica il route model binding.
Come
$callback di Broadcast::channel() puoi indicare un callable o il nome di una classe con un metodo join(). Nel caso di un nome di classe, Broadcaster::normalizeChannelHandlerToCallable() crea l’istanza tramite il container e poi chiama join().Sovrascrittura da parte dell’applicazione
Il file che l’applicazione passa awithBroadcasting() (di solito routes/channels.php) viene caricato all’interno di una callback booted registrata da withBroadcasting(). Le callback booted vengono eseguite dopo che il boot() di tutti i service provider è terminato, quindi la registrazione nel boot() del pacchetto avviene prima.
Broadcaster::channel() salva le callback in un array interno usando il nome del canale come chiave. Per questo, se l’applicazione registra lo stesso nome, la seconda registrazione sostituisce quella del pacchetto. Laravel non tratta un nome duplicato come un errore.
Per evitare la sovrascrittura, rendi univoco il nome del canale. Ad esempio, con un prefisso specifico del pacchetto come in acme.orders.{order}, diventa meno probabile che l’applicazione registri lo stesso nome.
Il nome del canale è un contratto pubblico con i client. Una volta deciso, non cambiarlo. Se lo cambi, i client esistenti non potranno più iscriversi.
Opzioni del canale e guard
Il terzo argomento$options di Broadcast::channel() viene salvato come configurazione del singolo canale. Se specifichi guards, i guard usati per l’autenticazione vengono provati in ordine.
guards, per l’autorizzazione viene usato l’utente predefinito della richiesta ($request->user()). Se specifichi guards, $request->user($guard) viene chiamato in ordine dall’inizio e viene usato il primo utente ottenuto. Se il pacchetto non fissa i nomi dei guard e li espone come valore di configurazione, l’applicazione può sceglierli.
Verificare la registrazione dei canali nei test
I canali registrati si ottengono comeCollection con getChannels() del driver. Le chiavi sono i nomi dei canali stessi.
/broadcasting/auth. I driver null e log non restituiscono nulla da auth(), quindi non si possono usare per questo test. I canali vengono registrati sul driver predefinito all’avvio dell’applicazione: imposta quindi BROADCAST_CONNECTION su reverb o pusher, ad esempio nel phpunit.xml dei test, prima di inviare la richiesta autenticata.
Attenzioni per la manutenzione
- Il nome del canale è un contratto pubblico. Se lo rinomini, i client esistenti non potranno più iscriversi.
- I canali basati su classi vengono risolti dal
Container. Per le dipendenze del costruttore usa tipi che il container può risolvere.
Riepilogo
L’autorizzazione dei canali di un pacchetto funziona registrandoBroadcast::channel() in boot(). Se il routes/channels.php dell’applicazione registra in seguito lo stesso nome, l’autorizzazione del pacchetto viene sostituita. Aggiungere un prefisso al nome del canale, separare la verifica in una classe e controllare il risultato di /broadcasting/auth con test HTTP rende il pacchetto più facile da mantenere.