Oggi, esploreremo il concetto di trasmissione nel framework web di Laravel. Permette di inviare notifiche al lato client quando succede qualcosa sul lato server. In questo articolo, useremo la libreria di terze parti di Pusher per inviare notifiche al lato client.
Se hai mai desiderato inviare notifiche dal server al client quando qualcosa accade su un server in Laravel, stai cercando la funzione di trasmissione.
Ad esempio, supponiamo di aver implementato un'applicazione di messaggistica che consente agli utenti del tuo sistema di inviare messaggi a vicenda. Ora, quando l'utente A invia un messaggio all'utente B, si desidera informare l'utente B in tempo reale. È possibile visualizzare un popup o una finestra di avviso che informa l'utente B sul nuovo messaggio!
È il caso d'uso perfetto per analizzare il concetto di trasmissione in Laravel, ed è quello che implementeremo in questo articolo.
Se ti stai chiedendo come il server potrebbe inviare notifiche al client, sta usando le prese sotto il cofano per realizzarlo. Comprendiamo il flusso di base delle prese prima di approfondire l'implementazione effettiva.
Non preoccuparti se sembra troppo in una volta sola; ne prenderai confidenza mentre ci spostiamo in questo articolo.
Successivamente, diamo un'occhiata al file di configurazione broadcast predefinito su config / broadcasting.php
.
env ('BROADCAST_DRIVER', 'log'), / * | ------------------------------------ -------------------------------------- | Collegamenti di trasmissione | ----------------------------------------------- --------------------------- | | Qui puoi definire tutte le connessioni di trasmissione che verranno utilizzate | per trasmettere eventi ad altri sistemi o tramite web socket. Esempi di | ogni tipo di connessione disponibile viene fornito all'interno di questo array. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'chiave' => env ('PUSHER_APP_KEY'), 'secret' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'),], 'redis' => ['driver' => 'redis', 'connection' => 'default',], 'log' => ['driver' => 'log ',],' null '=> [' driver '=>' null ',],],];
Di default, Laravel supporta più adattatori di trasmissione nel core stesso.
In questo articolo, useremo il Pusher
adattatore di trasmissione. A scopo di debug, è anche possibile utilizzare l'adattatore di registro. Certo, se stai usando il ceppo
adattatore, il client non riceverà alcuna notifica di eventi e verrà registrato solo su laravel.log
file.
Dalla prossima sezione in poi, ci occuperemo immediatamente dell'implementazione effettiva del caso d'uso di cui sopra.
Nella trasmissione, ci sono diversi tipi di canali: pubblico, privato e presenza. Quando vuoi trasmettere pubblicamente i tuoi eventi, è il canale pubblico che dovresti utilizzare. Al contrario, il canale privato viene utilizzato quando si desidera limitare le notifiche degli eventi a determinati canali privati.
Nel nostro caso d'uso, vogliamo avvisare gli utenti quando ricevono un nuovo messaggio. E per essere idoneo a ricevere le notifiche di trasmissione, l'utente deve aver effettuato l'accesso. Pertanto, nel nostro caso, dovremo utilizzare il canale privato.
Innanzitutto, è necessario abilitare il sistema di autenticazione Laravel predefinito in modo che funzioni quali registrazione, accesso e simili funzionino immediatamente. Se non sei sicuro di come farlo, la documentazione ufficiale fornisce una rapida panoramica di ciò.
Come useremo il Pusher
servizio di terze parti come server web-socket, è necessario creare un account con esso e assicurarsi di disporre delle necessarie credenziali API con la registrazione del post. Se hai difficoltà a crearlo, non esitare a chiedermelo nella sezione dei commenti.
Successivamente, dobbiamo installare l'SDK PHP Pusher in modo che la nostra applicazione Laravel possa inviare notifiche di trasmissione al server socket Web Pusher.
Nella root dell'applicazione Laravel, esegui il seguente comando per installarlo come pacchetto del compositore.
$ compositore richiede pusher / pusher-php-server "~ 3.0"
Ora, cambiamo il file di configurazione broadcast per abilitare l'adattatore Pusher come nostro driver di trasmissione predefinito.
env ('BROADCAST_DRIVER', 'pusher'), / * | ------------------------------------ -------------------------------------- | Collegamenti di trasmissione | ----------------------------------------------- --------------------------- | | Qui puoi definire tutte le connessioni di trasmissione che verranno utilizzate | per trasmettere eventi ad altri sistemi o tramite web socket. Esempi di | ogni tipo di connessione disponibile viene fornito all'interno di questo array. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'chiave' => env ('PUSHER_APP_KEY'), 'secret' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'opzioni' => ['cluster' => 'ap2', 'encrypted' => true],], 'redis' => ['driver' => 'redis', ' connection '=>' default ',],' log '=> [' driver '=>' log ',],' null '=> [' driver '=>' null ',],],];
Come puoi vedere, abbiamo modificato il driver di trasmissione predefinito su Pusher. Abbiamo anche aggiunto le opzioni di configurazione cluster e crittografate che dovresti avere dall'account Pusher in primo luogo.
Inoltre, sta recuperando i valori dalle variabili di ambiente. Quindi assicuriamoci di impostare le seguenti variabili in .ENV
file correttamente.
BROADCAST_DRIVER = pusher PUSHER_APP_ID = YOUR_APP_ID PUSHER_APP_KEY = YOUR_APP_KEY PUSHER_APP_SECRET = YOUR_APP_SECRET
Successivamente, ho dovuto apportare alcune modifiche in un paio di file Laravel di base per renderlo compatibile con l'ultimo SDK Pusher. Ovviamente, non consiglio di apportare modifiche al framework principale, ma evidenzierò solo ciò che deve essere fatto.
Vai avanti e apri il vendor / laravel / quadro / src / Illuminate / Broadcasting / emittenti / PusherBroadcaster.php
file. Basta sostituire lo snippet utilizzare Pusher;
con usa Pusher \ Pusher;
.
Quindi, apriamo il vendor / laravel / quadro / src / Illuminate / Broadcasting / BroadcastManager.php
file e apportare una modifica simile nel seguente frammento.
restituisce nuovo PusherBroadcaster (new \ Pusher \ Pusher ($ config ['key'], $ config ['secret'], $ config ['app_id'], Arr :: get ($ config, 'opzioni', [])) );
Infine, abilitiamo il servizio di trasmissione in config / app.php
rimuovendo il commento nella riga seguente.
App \ Providers \ BroadcastServiceProvider :: class,
Finora, abbiamo installato librerie specifiche per server. Nella prossima sezione, esamineremo le librerie client che devono essere installate.
Nella trasmissione, la responsabilità del lato client è quella di iscriversi ai canali e ascoltare gli eventi desiderati. Sotto il cofano, lo realizza aprendo una nuova connessione al server web-socket.
Fortunatamente, non è necessario implementare alcun complesso javascript per realizzarlo poiché Laravel fornisce già un'utile libreria client, Laravel Echo, che ci aiuta a gestire i socket sul lato client. Inoltre, supporta il servizio Pusher che useremo in questo articolo.
Puoi installare Laravel Echo usando il gestore pacchetti NPM. Ovviamente, è necessario installare node e npm in primo luogo se non li si possiede già. Il resto è piuttosto semplice, come mostrato nel seguente frammento.
$ npm installa laravel-echo
Quello che ci interessa è il node_modules / laravel-eco / dist / echo.js
file che dovresti copiare pubblici / echo.js
.
Sì, capisco, è un po 'eccessivo usare solo un singolo file JavaScript. Se non vuoi seguire questo esercizio, puoi scaricare il echo.js
file dal mio GitHub.
E con questo, abbiamo finito con l'installazione delle nostre librerie client.
Ricordiamo che stavamo parlando della configurazione di un'applicazione che consente agli utenti della nostra applicazione di inviare messaggi tra loro. D'altra parte, invieremo notifiche di trasmissione agli utenti che hanno effettuato l'accesso quando ricevono un nuovo messaggio da altri utenti.
In questa sezione creeremo i file necessari per implementare il caso d'uso che stiamo cercando.
Per cominciare, creiamo il Messaggio
modello che tiene reciprocamente i messaggi inviati dagli utenti.
$ php artisan make: model Message --migration
Abbiamo anche bisogno di aggiungere alcuni campi come a
, a partire dal
e Messaggio
alla nostra tabella dei messaggi. Quindi cambiamo il file di migrazione prima di eseguire il comando migrate.
incrementi ( 'id'); $ table-> intero ('from', FALSE, TRUE); $ table-> integer ('to', FALSE, TRUE); $ Tavola-> testo ( 'messaggio'); $ Tavola-> timestamp (); ); / ** * Invertire le migrazioni. * * @return void * / public function down () Schema :: dropIfExists ('messages');
Ora, eseguiamo il comando migrate che crea la tabella dei messaggi nel database.
$ php artisan migrate
Ogni volta che vuoi generare un evento personalizzato in Laravel, devi creare una classe per quell'evento. In base al tipo di evento, Laravel reagisce di conseguenza e intraprende le azioni necessarie.
Se l'evento è un evento normale, Laravel chiama le classi di ascolto associate. D'altra parte, se l'evento è di tipo broadcast, Laravel invia quell'evento al server web-socket configurato nel config / broadcasting.php
file.
Poiché nel nostro esempio utilizziamo il servizio Pusher, Laravel invierà eventi al server Pusher.
Usiamo il seguente comando artisan per creare una classe evento personalizzata-NewMessageNotification
.
$ php artisan make: evento NewMessageNotification
Quello dovrebbe creare il app / Eventi / NewMessageNotification.php
classe. Sostituiamo il contenuto di quel file con il seguente.
messaggio = $ messaggio; / ** * Ottieni i canali su cui l'evento dovrebbe essere trasmesso. * * @return Canale | array * / public function broadcastOn () return new PrivateChannel ('user.'. $ this-> message-> to);
La cosa importante da notare è che il NewMessageNotification
la classe implementa il ShouldBroadcastNow
interfaccia. Quindi, quando solleviamo un evento, Laravel sa che questo evento dovrebbe essere trasmesso.
In effetti, potresti anche implementare il ShouldBroadcast
interfaccia e Laravel aggiunge un evento nella coda degli eventi. Verrà elaborato dall'operatore della coda degli eventi quando avrà la possibilità di farlo. Nel nostro caso, vogliamo trasmetterlo subito, ed è per questo che abbiamo usato il ShouldBroadcastNow
interfaccia.
Nel nostro caso, vogliamo visualizzare un messaggio che l'utente ha ricevuto, e quindi abbiamo passato il Messaggio
modello nell'argomento costruttore. In questo modo, i dati verranno passati insieme all'evento.
Avanti, c'è il broadcastOn
metodo che definisce il nome del canale su cui verrà trasmesso l'evento. Nel nostro caso, abbiamo utilizzato il canale privato perché vogliamo limitare la trasmissione degli eventi agli utenti che hanno effettuato l'accesso.
Il $ This-> message-> a
variabile si riferisce all'ID dell'utente a cui verrà trasmesso l'evento. Pertanto, rende efficace il nome del canale utente. USER_ID
.
Nel caso di canali privati, il client deve autenticarsi prima di stabilire una connessione con il server socket Web. Si assicura che gli eventi trasmessi su canali privati vengano inviati solo ai client autenticati. Nel nostro caso, significa che solo gli utenti loggati potranno iscriversi al nostro canale utente. USER_ID
.
Se stai utilizzando la libreria client di Laravel Echo per l'iscrizione al canale, sei fortunato! Si occupa automaticamente della parte di autenticazione e devi solo definire i percorsi del canale.
Andiamo avanti e aggiungere un percorso per il nostro canale privato nel percorsi / channels.php
file.
id === (int) $ id; ); Broadcast :: channel ('user. ToUserId', function ($ user, $ toUserId) return $ user-> id == $ toUserId;);
Come puoi vedere, abbiamo definito il utente. toUserId
percorso per il nostro canale privato.
Il secondo argomento del metodo del canale dovrebbe essere una funzione di chiusura. Laravel passa automaticamente l'utente attualmente loggato come primo argomento della funzione di chiusura, e il secondo argomento viene solitamente recuperato dal nome del canale.
Quando il client tenta di iscriversi al canale privato utente. USER_ID
, la libreria di Laravel Echo esegue l'autenticazione necessaria in background utilizzando l'oggetto XMLHttpRequest o più comunemente noto come XHR.
Finora, abbiamo finito con il setup, quindi andiamo avanti e testarlo.
In questa sezione creeremo i file necessari per testare il nostro caso d'uso.
Andiamo avanti e creare un file di controller su App / HTTP / Controller / MessageController.php
con i seguenti contenuti.
middleware ( 'auth'); public function index () $ user_id = Auth :: user () -> id; $ data = array ('user_id' => $ user_id); visualizzazione di ritorno ('broadcast', $ data); public function send () // ... // messaggio viene inviato $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('a', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Message-> save (); // desidera trasmettere l'evento evento NewMessageNotification (new NewMessageNotification ($ message)); // ...
Nel indice
metodo, stiamo usando il trasmissione
vista, quindi creiamo il Resources / views / broadcast.blade.php
guarda anche il file.
Test La nuova notifica verrà avvisata in tempo reale!
E, naturalmente, dobbiamo aggiungere percorsi anche nel percorsi / web.php
file.
Route :: get ('message / index', 'MessageController @ index'); Route :: get ('message / send', 'MessageController @ send');
Nel metodo del costruttore della classe controller, puoi vedere che abbiamo usato il auth
middleware per assicurarsi che i metodi del controller siano accessibili solo dagli utenti loggati.
Avanti, c'è il indice
metodo che rende il trasmissione
vista. Inseriamo il codice più importante nel file di visualizzazione.
In primo luogo, carichiamo le librerie client necessarie, Laravel Echo e Pusher, permettendoci di aprire la connessione web-socket al server socket Web Pusher.
Successivamente, creiamo l'istanza di Echo fornendo Pusher come nostro adattatore di trasmissione e altre informazioni relative al Pusher necessarie.
Andando oltre, usiamo il metodo privato di Echo per iscriversi al canale privato utente. USER_ID
. Come discusso in precedenza, il client deve autenticarsi prima di iscriversi al canale privato. Quindi il Eco
oggetto esegue l'autenticazione necessaria inviando l'XHR in background con i parametri necessari. Finalmente, Laravel prova a trovare il utente. USER_ID
percorso, e dovrebbe corrispondere al percorso che abbiamo definito nel percorsi / channels.php
file.
Se tutto va bene, dovresti avere una connessione web-socket aperta con il server web-socket Pusher, ed elencare gli eventi sul utente. USER_ID
canale! D'ora in poi, saremo in grado di ricevere tutti gli eventi in arrivo su questo canale.
Nel nostro caso, vogliamo ascoltare il NewMessageNotification
evento e quindi abbiamo usato il ascolta
metodo del Eco
oggetto di raggiungerlo. Per semplificare le cose, avvertiremo semplicemente il messaggio che abbiamo ricevuto dal server Pusher.
Quindi questa era la configurazione per ricevere eventi dal server web-socket. Successivamente, passeremo attraverso il inviare
metodo nel file controller che solleva l'evento broadcast.
Inseriamo rapidamente il codice di inviare
metodo.
funzione pubblica send () // ... // messaggio viene inviato $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('a', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Message-> save (); // desidera trasmettere l'evento evento NewMessageNotification (new NewMessageNotification ($ message)); // ...
Nel nostro caso, notificheremo agli utenti che hanno effettuato l'accesso quando ricevono un nuovo messaggio. Quindi abbiamo cercato di imitare quel comportamento nel inviare
metodo.
Successivamente, abbiamo usato il evento
funzione di aiuto per aumentare il NewMessageNotification
evento. Dal momento che il NewMessageNotification
l'evento è di ShouldBroadcastNow
digita, Laravel carica la configurazione di trasmissione predefinita da config / broadcasting.php
file. Infine, trasmette il NewMessageNotification
evento al server Web-socket configurato sul utente. USER_ID
canale.
Nel nostro caso, l'evento verrà trasmesso al server web-socket Pusher sul utente. USER_ID
canale. Se l'ID dell'utente destinatario è 1
, l'evento sarà trasmesso su user.1
canale.
Come abbiamo discusso in precedenza, abbiamo già una configurazione che ascolta gli eventi su questo canale, quindi dovrebbe essere in grado di ricevere questo evento e la casella di avviso viene visualizzata all'utente!
Andiamo avanti e spieghiamo come si suppone di testare il caso d'uso che abbiamo costruito finora.
Apri l'URL http: // your-laravel-site-domain / message / index nel tuo browser. Se non hai ancora effettuato l'accesso, verrai reindirizzato alla schermata di accesso. Una volta effettuato l'accesso, dovresti vedere la visualizzazione broadcast che abbiamo definito in precedenza, non ancora niente di speciale.
In effetti, Laravel ha già fatto un bel po 'di lavoro in background per te. Come abbiamo abilitato il Pusher.logToConsole
impostazione fornita dalla libreria client Pusher, registra tutto nella console del browser per scopi di debug. Vediamo cosa viene registrato sulla console quando si accede alla pagina http: // your-laravel-site-domain / message / index.
Pusher: stato modificato: inizializzato -> collegamento Pusher: Connessione: "transport": "ws", "url": "wss: //ws-ap2.pusher.com: 443 / app / c91c1b7e8c6ece46053b? Protocol = 7 & client = js & versione = 4.1.0 & flash = false " Pusher: Connessione: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Pusher: stato modificato: connessione -> connesso con nuovo ID socket 1386.68660 Pusher: evento inviato: " evento ":" pusher: subscribe "," data ": " auth ":" c91c1b7e8c6ece46053b: cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d "," channel ":" private-user.2 " Pusher: Event recd: " event ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" private-user.2 " Pusher: nessuna callback su private-user.2 per pusher: subscription_succected
Ha aperto la connessione web-socket con il server web-socket Pusher e si è iscritto per ascoltare gli eventi sul canale privato. Naturalmente, potresti avere un nome di canale diverso nel tuo caso in base all'ID dell'utente con cui hai effettuato l'accesso. Ora, teniamo aperta questa pagina mentre ci spostiamo per testare il inviare
metodo.
Quindi, apriamo http: // your-laravel-site-domain / message / send URL nell'altra scheda o in un altro browser. Se stai per utilizzare un browser diverso, devi accedere per poter accedere a quella pagina.
Non appena apri la pagina http: // your-laravel-site-domain / message / send, dovresti essere in grado di vedere un messaggio di avviso nell'altra scheda all'indirizzo http: // your-laravel-site-domain / message /indice.
Passiamo alla console per vedere cosa è appena successo.
Pusher: Event recd: "event": "App \\ Events \\ NewMessageNotification", "data": "message": "id": 57, "from": 1, "a": 2, "messaggio ":" Demo messaggio da utente 1 a utente 2 "," created_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 "," canale ":" private-user.2"
Come puoi vedere, ti dice che hai appena ricevuto il App \ Eventi \ NewMessageNotification
evento dal server socket Web Pusher sul private-user.2
canale.
In effetti, puoi vedere cosa sta succedendo là fuori anche alla fine del Pusher. Vai al tuo account Pusher e vai alla tua applicazione. Sotto il mettere a punto consolle, dovresti essere in grado di vedere i messaggi registrati.
E questo ci porta alla fine di questo articolo! Spero che non sia stato un granché in un solo tentativo, visto che ho cercato di semplificare le cose al meglio delle mie conoscenze.
Oggi abbiamo analizzato una delle funzioni meno discusse della trasmissione di Laravel. Ti consente di inviare notifiche in tempo reale tramite socket web. Nel corso di questo articolo, abbiamo creato un esempio del mondo reale che ha dimostrato il concetto di cui sopra.
.