Astăzi, vom explora conceptul de difuzare în cadrul web Laravel. Acesta vă permite să trimiteți notificări către partea clientului atunci când se întâmplă ceva pe partea de server. În acest articol, vom folosi biblioteca Pusher terță parte pentru a trimite notificări către partea clientului.
Dacă ați dorit vreodată să trimiteți notificări de la server către client atunci când se întâmplă ceva pe un server din Laravel, căutați funcția de difuzare.
De exemplu, să presupunem că ați implementat o aplicație de mesagerie care permite utilizatorilor sistemului dvs. să vă trimită mesaje unul altuia. Acum, atunci când utilizatorul A trimite un mesaj către utilizatorul B, doriți să îl notificați pe utilizatorul B în timp real. Puteți afișa o fereastră pop-up sau o alertă care informează utilizatorul B despre noul mesaj!
Este cazul perfect pentru a trece prin conceptul de difuzare în Laravel, și asta vom implementa în acest articol.
Dacă vă întrebați cum poate serverul să trimită notificări clientului, utilizează prize sub capotă pentru ao realiza. Să înțelegem fluxul de bază al soclurilor înainte de a ne scufunda mai adânc în implementarea reală.
Nu vă faceți griji dacă pare prea mult într-o singură călătorie; veți obține o atârnă de ea în timp ce trecem prin acest articol.
Apoi, să aruncăm o privire la fișierul de configurare difuzat implicit la config / broadcasting.php
.
env ("BROADCAST_DRIVER", "log"), / * | ------------------------------------ -------------------------------------- Conexiuni de radiodifuziune | ----------------------------------------------- --------------------------- | Aici puteți defini toate conexiunile de difuzare care vor fi utilizate pentru a difuza evenimente către alte sisteme sau pe site-uri Web. Eșantioane de fiecare tip de conexiune disponibilă este furnizat în interiorul acestei matrice. | * '/' conexiuni '=> [' pusher '=>' pusher ',' key '=> env (' PUSHER_APP_KEY '),' secret '=> env (' PUSHER_APP_SECRET ' => env ('PUSHER_APP_ID'),], 'redis' => ['driver' => 'redis', 'connection' => ',],' null '=> [' conducătorul auto '=>' null ',],],];
În mod implicit, Laravel acceptă mai multe adaptoare difuzate în nucleul propriu-zis.
În acest articol, vom folosi Pusher
difuzor adaptor. Pentru depanare, puteți utiliza și adaptorul de jurnal. Desigur, dacă utilizați Buturuga
adaptor, clientul nu va primi notificări de eveniment și va fi conectat la laravel.log
fişier.
Din următoarea secțiune, vom începe imediat să aruncăm o privire asupra implementării reale a cazului de utilizare menționat mai sus.
În emisie, există diferite tipuri de canale - publice, private și prezență. Când doriți să difuzați evenimentele în mod public, acesta este canalul public pe care ar trebui să îl utilizați. În schimb, canalul privat este utilizat atunci când doriți să restricționați notificările de eveniment la anumite canale private.
În cazul nostru de utilizare, dorim să-i înștiințăm pe utilizatori atunci când primesc un mesaj nou. Și pentru a fi eligibil pentru a primi notificări de difuzare, utilizatorul trebuie să fie conectat. Astfel, va trebui să folosim canalul privat în cazul nostru.
În primul rând, trebuie să activați sistemul de autentificare Laravel implicit, astfel încât funcții cum ar fi înregistrarea, datele de conectare și altele asemănătoare să funcționeze din cutie. Dacă nu sunteți sigur cum să faceți acest lucru, documentația oficială oferă o perspectivă rapidă asupra acestui aspect.
Așa cum vom folosi Pusher
serviciul terță parte ca server de web-socket, trebuie să creați un cont cu acesta și să vă asigurați că aveți acreditările API necesare cu înregistrarea dvs. postare. Dacă vă confruntați cu probleme în crearea acestuia, nu ezitați să mă întrebați în secțiunea de comentarii.
Apoi, trebuie să instalați Pusher PHP SDK astfel încât aplicația noastră Laravel să poată trimite notificări de difuzare la serverul Web-socket Pusher.
În root-ul aplicației Laravel, executați următoarea comandă pentru ao instala ca pachet compozitor.
$ compozitorul are nevoie de pushher / pushher-php-server "~ 3.0"
Acum, să schimbăm fișierul de configurare a difuzării pentru a activa adaptorul Pusher ca driver difuzat implicit.
env ("BROADCAST_DRIVER", "împingător"), / * | ------------------------------------ -------------------------------------- Conexiuni de radiodifuziune | ----------------------------------------------- --------------------------- | Aici puteți defini toate conexiunile de difuzare care vor fi utilizate pentru a difuza evenimente către alte sisteme sau pe site-uri Web. Eșantioane de fiecare tip de conexiune disponibilă este furnizat în interiorul acestei matrice. | * '/' conexiuni '=> [' pusher '=>' pusher ',' key '=> env (' PUSHER_APP_KEY '),' secret '=> env (' PUSHER_APP_SECRET ' => 'env (' PUSHER_APP_ID '),' opțiuni '=> [' cluster '=>' ap2 ',' encrypted '=> true],' redis ' conexiune '=>' implicit ',],' log '=> [' driver '=>' log ',],' null '=> [' driver '=>' null ',];
După cum puteți vedea, am schimbat driverul de difuzare implicit în Pusher. De asemenea, am adăugat opțiuni de configurare criptate și cluster pe care ar trebui să le primim din contul Pusher în primul rând.
De asemenea, se preiau valori din variabilele de mediu. Deci, să ne asigurăm că setăm următoarele variabile în .env
fișierul corect.
BROADCAST_DRIVER = împingător PUSHER_APP_ID = YOUR_APP_ID PUSHER_APP_KEY = YOUR_APP_KEY PUSHER_APP_SECRET = YOUR_APP_SECRET
Apoi, a trebuit să fac câteva modificări în câteva fișiere de bază Laravel pentru a fi compatibil cu ultimul SDK Pusher. Desigur, nu recomand să faceți nicio modificare în cadrul central, dar voi sublinia doar ce trebuie făcut.
Mergeți și deschideți furnizor / laravel / cadru / src / Illuminate / Difuzare / stații de emisie / PusherBroadcaster.php
fişier. Doar înlocuiți fragmentul utilizați dispozitivul de împingere;
cu utilizați Pusher \ Pusher;
.
Apoi, hai să deschidem furnizor / laravel / cadru / src / Illuminate / Difuzare / BroadcastManager.php
fișier și efectuați o modificare similară în fragmentul următor.
($ config ['key'], $ config ['secret'], $ config ['app_id'], Arr :: get ($ config, 'options', [ );
În cele din urmă, permiteți serviciului de difuzare în config / app.php
prin eliminarea comentariului în următoarea linie.
App \ Furnizori \ BroadcastServiceProvider :: clasa,
Până acum, am instalat biblioteci specifice serverului. În secțiunea următoare, vom trece prin bibliotecile client care trebuie instalate, de asemenea.
În emisie, responsabilitatea clientului este să vă abonați la canale și să ascultați evenimentele dorite. Sub capotă, se realizează prin deschiderea unei noi conexiuni la serverul Web-socket.
Din fericire, nu trebuie să implementăm chestii JavaScript complexe pentru ao realiza, Laravel oferind deja o bibliotecă de client utilă, Laravel Echo, care ne ajută să facem afaceri cu socket-uri pe partea clientului. De asemenea, acceptă serviciul Pusher pe care îl vom folosi în acest articol.
Puteți instala Laravel Echo utilizând managerul de pachete NPM. Desigur, trebuie să instalați nod și npm în primul rând dacă nu le aveți deja. Restul este destul de simplu, așa cum se arată în fragmentul următor.
$ npm instalează laravel-echo
Ceea ce ne interesează este node_modules / laravel-ecou / dist / echo.js
fișierul pe care ar trebui să-l copiați publice / echo.js
.
Da, înțeleg, este un pic de overkill pentru a obține doar un singur fișier JavaScript. Dacă nu doriți să treceți prin acest exercițiu, puteți descărca echo.js
fișier din GitHub-ul meu.
Și cu asta, am terminat cu configurarea bibliotecilor noastre de clienți.
Amintiți-vă că am vorbit despre crearea unei aplicații care permite utilizatorilor aplicației noastre să trimită mesaje reciproc. Pe de altă parte, vom trimite notificări difuzate utilizatorilor care sunt conectați când primesc un mesaj nou de la alți utilizatori.
În această secțiune, vom crea fișierele necesare pentru a implementa cazul de utilizare pe care îl căutăm.
Pentru a începe, să creați Mesaj
model care conține mesajele trimise de utilizatori între ele.
$ php artizan face: model Mesaj - migrare
Trebuie, de asemenea, să adăugăm câțiva câmpuri la
, din
și mesaj
la masa mesageriei noastre. Deci, să schimbăm fișierul de migrare înainte de a rula comanda de migrare.
incremente ( 'id'); $ table-> integer ('de la', FALSE, TRUE); $ table-> întreg ('to', FALSE, TRUE); $ Table-> text ( 'mesaj'); $ Table-> timestamps (); ); / ** * Reveniți la migrații. * * @return void * / funcția publică în jos () Schema :: dropIfExists ('mesaje');
Acum, să executați comanda de migrare care creează tabela de mesaje în baza de date.
$ php artizan migrează
Ori de câte ori doriți să ridicați un eveniment personalizat în Laravel, ar trebui să creați o clasă pentru acel eveniment. Pe baza tipului de eveniment, Laravel reacționează în mod corespunzător și ia măsurile necesare.
Dacă evenimentul este un eveniment normal, Laravel apelează clasele de ascultători asociate. Pe de altă parte, dacă evenimentul este de tip broadcast, Laravel trimite acel eveniment la serverul Web-socket care este configurat în config / broadcasting.php
fişier.
Pe măsură ce folosim serviciul Pusher în exemplul nostru, Laravel va trimite evenimente către serverul Pusher.
Să utilizăm următoarea comandă artizanală pentru a crea o clasă de eveniment personalizat-NewMessageNotification
.
$ php artisan face: eveniment NewMessageNotification
Aceasta ar trebui să creeze app / Evenimente / NewMessageNotification.php
clasă. Să înlocuim conținutul acelui fișier cu următoarele.
mesaj = $ mesaj; / ** * Obțineți canalele la care ar trebui să difuzeze evenimentul. * * @return Channel | array * / public function broadcastOn () returneaza noul PrivateChannel ('user.'. $ this-> message-> to);
Cel mai important lucru de reținut este faptul că NewMessageNotification
clasa implementează ShouldBroadcastNow
interfață. Astfel, când ridicăm un eveniment, Laravel știe că acest eveniment ar trebui difuzat.
De fapt, puteți implementa și ShouldBroadcast
și Laravel adaugă un eveniment în coada de evenimente. Acesta va fi procesat de către lucrătorul de coadă de evenimente atunci când primește o șansă să facă acest lucru. În cazul nostru, vrem să îl difuzăm imediat și de aceea am folosit-o ShouldBroadcastNow
interfață.
În cazul nostru, dorim să afișăm un mesaj pe care utilizatorul l-a primit și, astfel, l-am trecut Mesaj
model în argumentul constructorului. În acest fel, datele vor fi transmise împreună cu evenimentul.
Apoi, există broadcastOn
care definește numele canalului pe care va fi difuzat evenimentul. În cazul nostru, am folosit canalul privat deoarece dorim să restricționăm difuzarea evenimentului la utilizatorii conectați.
$ This-> Message> to
variabila se referă la ID-ul utilizatorului la care va fi difuzat evenimentul. Astfel, acesta face în mod eficient numele canalului utilizator. USER_ID
.
În cazul canalelor private, clientul trebuie să se autentifice înainte de a stabili o conexiune cu serverul Web-socket. Se asigură că evenimentele difuzate pe canale private sunt trimise numai clienților autentificați. În cazul nostru, înseamnă că numai utilizatorii conectați vor putea să se aboneze la canalul nostru utilizator. USER_ID
.
Dacă utilizați biblioteca client Laravel Echo pentru abonamentul la canal, aveți noroc! Se ocupă automat de partea de autentificare și trebuie doar să definiți rutele canalului.
Să mergem mai departe și să adăugăm un traseu pentru canalul nostru privat în rute / channels.php
fişier.
id === (int) $ id; ); Difuzare :: canal ('utilizator. ToUserId', functie ($ user, $ toUserId) return $ user-> id == $ toUserId;);
După cum puteți vedea, am definit utilizator. toUserId
traseu pentru canalul nostru privat.
Al doilea argument al metodei de canal ar trebui să fie o funcție de închidere. Laravel trece în mod automat utilizatorul conectat în prezent ca primul argument al funcției de închidere, iar al doilea argument este de obicei preluat din numele canalului.
Când clientul încearcă să se aboneze la canalul privat utilizator. USER_ID
, biblioteca Laravel Echo face autentificarea necesară în fundal folosind obiectul XMLHttpRequest sau mai cunoscut ca XHR.
Până acum, am terminat cu configurarea, așa că hai să mergem înainte și să încercăm.
În această secțiune, vom crea fișierele necesare pentru a testa cazul nostru de utilizare.
Să mergem mai departe și să creăm un dosar de controler la app / HTTP / Controllers / MessageController.php
cu următorul conținut.
middleware ( 'auth'); indexul funcției publice () $ user_id = Auth :: user () -> id; $ data = array ('user_id' => $ user_id); afișare retur ("difuzare", date $); funcția publică send () // ... // mesajul este trimis $ message = new Message; $ message-> setAttribute ('de la', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Message> Salvare (); // doriți să difuzați evenimentul Eveniment NewMessageNotification (noul NewMessageNotification ($ message)); // ...
În index
metoda, folosim difuzare
vizualizați, deci să creați Resurse / opinii / broadcast.blade.php
vizualizați și fișierul.
Test Notificarea nouă va fi anunțată în timp real!
Și, bineînțeles, trebuie să adăugăm și rute în rute / web.php
fişier.
Route :: get ('mesaj / index', 'MessageController @ index'); Traseu: get ('message / send', 'MessageController @ send');
În metoda constructor a clasei de controler, puteți vedea că am folosit AUTH
middleware pentru a vă asigura că metodele controlerului sunt accesate numai de utilizatorii conectați.
Mai departe, există index
metoda care face difuzare
vedere. Să tragem cel mai important cod din fișierul de vizualizare.
În primul rând, încărcăm bibliotecile de client necesare, Laravel Echo și Pusher, permițându-ne să deschidem conexiunea Web-socket la serverul Web-socket Pusher.
Apoi, vom crea instanța Echo oferind Pusher ca adaptorul nostru de difuzare și alte informații necesare legate de Pusher.
Mai departe, folosim metoda privată a Echo pentru a vă abona la canalul privat utilizator. USER_ID
. După cum am discutat mai devreme, clientul trebuie să se autentifice înainte de a se abona la canalul privat. Astfel, Ecou
Obiectul efectuează autentificarea necesară trimițând XHR în fundal cu parametrii necesari. În cele din urmă, Laravel încearcă să găsească utilizator. USER_ID
traseu și ar trebui să corespundă rutei pe care am definit-o în rute / channels.php
fişier.
Dacă totul merge bine, ar trebui să aveți o conexiune Web-socket deschisă cu serverul Web-socket Pusher, și să menționați evenimentele de pe utilizator. USER_ID
canal! De acum încolo, vom putea primi toate evenimentele de pe acest canal.
În cazul nostru, dorim să ascultăm pentru NewMessageNotification
eveniment și, prin urmare, am folosit asculta
metodă a Ecou
obiect pentru ao realiza. Pentru a păstra lucrurile simple, vom alerta mesajul pe care l-am primit de la serverul Pusher.
Așa a fost configurarea pentru recepționarea evenimentelor de pe serverul web-sockets. Apoi, vom trece prin trimite
în fișierul controlerului care ridică evenimentul de difuzare.
Să tragem rapid codul trimite
metodă.
funcția publică trimite () // ... // mesajul este trimis $ message = new Message; $ message-> setAttribute ('de la', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Message> Salvare (); // doriți să difuzați evenimentul Eveniment NewMessageNotification (noul NewMessageNotification ($ message)); // ...
În cazul nostru, vom notifica utilizatorii conectați atunci când primesc un mesaj nou. Așa că am încercat să imităm acest comportament în trimite
metodă.
Apoi, am folosit eveniment
helper funcția de a ridica NewMessageNotification
eveniment. Din moment ce NewMessageNotification
evenimentul este de ShouldBroadcastNow
tip, Laravel încarcă configurația difuzată implicită din config / broadcasting.php
fişier. În cele din urmă, acesta difuzează NewMessageNotification
eveniment la serverul de Web-socket configurat pe utilizator. USER_ID
canal.
În cazul nostru, evenimentul va fi difuzat pe serverul Web-socket Pusher pe utilizator. USER_ID
canal. Dacă este numele ID al utilizatorului destinatar 1
, evenimentul va fi difuzat pe user.1
canal.
Așa cum am discutat mai devreme, avem deja o configurație care ascultă evenimente de pe acest canal, astfel încât ar trebui să poată primi acest eveniment și caseta de alertă este afișată utilizatorului!
Să mergem mai departe și să mergem prin modul în care trebuie să testați cazul de utilizare pe care l-am construit până acum.
Deschideți adresa URL http: // your-laravel-site-domain / message / index în browserul dvs. Dacă nu sunteți încă conectat (ă), veți fi redirecționat (ă) la ecranul de conectare. După ce v-ați conectat, ar trebui să vedeți vizualizarea difuzată pe care am definit-o mai devreme - nimic fantezist încă.
De fapt, Laravel a făcut deja destul de multă muncă în fundal pentru tine. Așa cum am activat Pusher.logToConsole
setare oferită de biblioteca client Pusher, aceasta înregistrează totul în consola browser pentru scopuri de depanare. Să vedem ce se înregistrează în consola când accesați pagina http: // your-laravel-site-site / message / index.
Pusher: Starea schimbată: inițializată -> conectare Pusher: Conectare: "transport": "ws", "url": "wss: //ws-ap2.pusher.com: 443 / app / c91c1b7e8c6ece46053b? Protocol = 7 & client = js & version = 4.1.0 & flash = false " Pusher: Conectare: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Pusher: Starea schimbată: conectarea -> conectată la ID-ul socket nou 1386.68660 Pusher: Eveniment trimis: " event ": pushher: subscribe, data: c91c1b7e8c6ece46053b cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d "," canal ":" privat-utilizator.2 " Pusher: Eveniment recd: " eveniment ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" private-user.2 " Pusher: Nu există apeluri de tip privat pentru utilizator.2 pentru împingător: abonamentul a urmat
A deschis conexiunea web-socket cu serverul Web-socket Pusher și sa înscris pentru a asculta evenimentele de pe canalul privat. Bineînțeles, ați putea avea un nume de canal diferit în cazul dvs. pe baza ID-ului utilizatorului cu care v-ați conectat. Acum, să păstrăm această pagină deschisă pe măsură ce încercăm să încercăm trimite
metodă.
Apoi, deschideți URL-ul http: // your-laravel-site-site / message / send în altă filă sau într-un browser diferit. Dacă intenționați să utilizați un browser diferit, trebuie să vă conectați pentru a putea accesa acea pagină.
De îndată ce deschideți pagina http: // your-laravel-site-site / message / send, ar trebui să puteți vedea un mesaj de alertă în celălalt fișier de la http: // your-laravel-site-domain / message /index.
Să navigăm la consola pentru a vedea ce sa întâmplat.
Pusher: Evenimentul recd: "event": "App \\ Events \\ NewMessageNotification", "data": "message": mesajul " ":" Mesaj demo de la utilizator 1 la utilizator 2 "," create_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 " canal ":" privat-user.2"
După cum puteți vedea, vă spune că tocmai ați primit App \ Evenimente \ NewMessageNotification
eveniment de la serverul Web-socket Pusher pe privat-user.2
canal.
De fapt, puteți vedea ce se întâmplă acolo la sfârșitul Pusher. Accesați contul Pusher și navigați la aplicația dvs. Sub debug Consolă, ar trebui să puteți vedea mesajele înregistrate.
Și asta ne aduce la sfârșitul acestui articol! Sperăm că nu a fost prea mult într-o singură mișcare, deoarece am încercat să simplific lucrurile cât de bine știu.
Astăzi, am trecut printr-una dintre cele mai puțin discutate trăsături ale difuzării Laravel. Vă permite să trimiteți notificări în timp real utilizând prize web. Pe tot parcursul acestui articol, am construit un exemplu din lumea reală care a demonstrat conceptul menționat mai sus.
.