Hvordan Laravel Broadcasting Works

I dag skal vi utforske konseptet kringkasting i Laravel web-rammeverket. Det lar deg sende varsler til klientsiden når det skjer noe på serversiden. I denne artikkelen skal vi bruke tredjeparts Pusher-biblioteket til å sende varsler til klientsiden.

Hvis du noen gang har ønsket å sende varsler fra serveren til klienten når noe skjer på en server i Laravel, leter du etter kringkastingsfunksjonen.

For eksempel, anta at du har implementert et meldingsprogram som lar brukere av systemet sende meldinger til hverandre. Nå, når bruker A sender en melding til bruker B, vil du varsle bruker B i sanntid. Du kan vise en popup- eller en varslingsboks som informerer bruker B om den nye meldingen!

Det er det perfekte brukssaken å gå gjennom konseptet kring kringkasting i Laravel, og det er det vi skal implementere i denne artikkelen.

Hvis du lurer på hvordan serveren kunne sende meldinger til klienten, bruker den kontakter under hetten for å oppnå det. La oss forstå grunnstrømmen av stikkontakter før vi dykker dypere inn i selve implementeringen.

  • For det første trenger du en server som støtter nettokontakter protokollen og lar klienten etablere en nettkontaktforbindelse.
  • Du kan implementere din egen server eller bruke en tredjepartstjeneste som Pusher. Vi foretrekker sistnevnte i denne artikkelen.
  • Klienten initierer en nettkontakt til web socket serveren og mottar en unik identifikator ved vellykket forbindelse.
  • Når forbindelsen er vellykket, abonnerer klienten på bestemte kanaler der den ønsker å motta hendelser.
  • Til slutt registrerer klienten hendelser som den vil høre på under den abonnerte kanalen.
  • Nå på server siden, når en bestemt hendelse skjer, informerer vi web-socket-serveren ved å gi den med kanalnavnet og hendelsesnavnet.
  • Og til slutt sender web-socket-serveren den hendelsen til registrerte klienter på den aktuelle kanalen.

Ikke bekymre deg hvis det ser ut som for mye på en gang Du vil få tak i det når vi beveger deg gjennom denne artikkelen.

Deretter skal vi se på standard kringkastingskonfigurasjonsfilen på config / broadcasting.php.

 env ('BROADCAST_DRIVER', 'logg'), / * | ------------------------------------ -------------------------------------- | Broadcast Connections | ----------------------------------------------- --------------------------- | | Her kan du definere alle kringkastingstilkoblingene som skal brukes | å kringkaste hendelser til andre systemer eller over websockets. Prøver av | Hver tilgjengelig type tilkobling er gitt inne i denne gruppen. | * / 'connections' => ['driver' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'hemmelig' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'redis' => ['driver' => 'redis', 'connection' => 'standard',], 'log' => ['driver' => 'logg ',],' null '=> [' driver '=>' null ',],],];

Som standard støtter Laravel flere kringkastingsadaptere i selve kjernen.

I denne artikkelen skal vi bruke Pusher kringkastingsadapter. For feilsøkingsformål kan du også bruke loggadapteren. Selvfølgelig, hvis du bruker Logg Adapter, vil klienten ikke motta noen hendelsesvarsler, og det blir bare logget på laravel.log fil.

Fra neste avsnitt videre vil vi med en gang dykke inn i selve implementeringen av ovennevnte bruksveske.

Sette opp forutsetningene

I kringkasting er det forskjellige typer kanaler - offentlig, privat og tilstedeværelse. Når du vil kringkaste hendelsene dine offentlig, er det den offentlige kanalen du skal bruke. Omvendt brukes den private kanalen når du vil begrense hendelsesvarsler til bestemte private kanaler.

I vårt brukstilfelle vil vi varsle brukere når de får en ny melding. Og for å være kvalifisert til å motta sendingsvarsler, må brukeren være logget inn. Vi må derfor bruke den private kanalen i vårt tilfelle.

Kjerneautentiseringsfunksjon

For det første må du aktivere standard Laravel-autentiseringssystemet slik at funksjoner som registrering, innlogging og lignende fungerer ut av boksen. Hvis du ikke er sikker på hvordan du gjør det, gir den offisielle dokumentasjonen et raskt innblikk i det.

Pusher SDK-installasjon og konfigurasjon

Som vi skal bruke Pusher Tjenesten fra tredjepart som vår web-socket server, må du opprette en konto med den og sørg for at du har de nødvendige API-legitimasjonene med din postregistrering. Hvis du står overfor problemer med å opprette det, ikke nøl med å spørre meg i kommentarseksjonen.

Deretter må vi installere Pusher PHP SDK slik at Laravel-applikasjonen kan sende kringkastingsvarsler til Pusher web-socket server.

Kjør følgende kommando i Laravel-programroten, for å installere den som en komponentpakke.

$ komponent krever pusher / pusher-php-server "~ 3,0"

La oss nå endre kringkastingskonfigurasjonsfilen for å aktivere Pusher-adapteren som standard sendingsdriver.

 env ('BROADCAST_DRIVER', 'pusher'), / * | ------------------------------------ -------------------------------------- | Broadcast Connections | ----------------------------------------------- --------------------------- | | Her kan du definere alle kringkastingstilkoblingene som skal brukes | å kringkaste hendelser til andre systemer eller over websockets. Prøver av | Hver tilgjengelig type tilkobling er gitt inne i denne gruppen. | * / 'connections' => ['driver' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'hemmelig' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'options' => ['cluster' => 'ap2', 'kryptert' => sant]], 'redis' => ['driver' => 'redis' tilkobling '=>' standard ',],' log '=> [' driver '=>' logg ',],' null '=> [' driver '=>' null ',]]]

Som du kan se, har vi endret standard kringkastingsdriver til Pusher. Vi har også lagt til klynge og krypterte konfigurasjonsalternativer som du burde ha fått fra Pusher-kontoen i utgangspunktet.

Det henter også verdier fra miljøvariabler. Så la oss sørge for at vi stiller følgende variabler i .env fil riktig.

BROADCAST_DRIVER = pusher PUSHER_APP_ID = YOUR_APP_ID PUSHER_APP_KEY = YOUR_APP_KEY PUSHER_APP_SECRET = YOUR_APP_SECRET

Deretter måtte jeg gjøre noen endringer i et par kjerne Laravel-filer for å gjøre det kompatibelt med den nyeste Pusher SDK. Selvfølgelig anbefaler jeg ikke å gjøre noen endringer i kjernerammen, men jeg vil bare markere hva som må gjøres.

Gå videre og åpne leverandør / laravel / rammeverk / src / Illuminate /-kringkasting / kringkastere / PusherBroadcaster.php fil. Bare erstatt koden bruk Pusher; med bruk Pusher \ Pusher;.

Deretter la vi åpne leverandør / laravel / rammeverk / src / Illuminate /-kringkasting / BroadcastManager.php fil og gjør en lignende endring i følgende utdrag.

returner ny PusherBroadcaster (ny \ Pusher \ Pusher ($ config ['key'], $ config ['hemmelig'], $ config ['app_id'], Arr :: get ($ config, 'options', []) );

Til slutt, la oss aktivere kringkastingstjenesten i config / app.php ved å fjerne kommentaren i den følgende linjen.

App \ Providers \ BroadcastServiceProvider :: klasse,

Så langt har vi installert serverspesifikke biblioteker. I neste avsnitt går vi gjennom klientbiblioteker som må installeres også.

Pusher og Laravel Echo-bibliotek - Installasjon og konfigurering

I kringkasting er kundens ansvar ansvarlig for å abonnere på kanaler og lytte etter ønskede hendelser. Under hetten gjør den det ved å åpne en ny forbindelse til web-socket serveren.

Heldigvis trenger vi ikke å implementere noen komplekse JavaScript-ting for å oppnå det, da Laravel allerede gir et nyttig klientbibliotek, Laravel Echo, som hjelper oss med å håndtere stikkontakter på klientsiden. Det støtter også Pusher-tjenesten som vi skal bruke i denne artikkelen.

Du kan installere Laravel Echo ved hjelp av NPM pakkebehandling. Selvfølgelig må du installere node og npm i utgangspunktet hvis du ikke allerede har dem. Resten er ganske enkel, som vist i følgende utdrag.

$ npm installer laravel-ekko

Det vi er interessert i er node_modules / laravel-ekko / dist / echo.js fil som du skal kopiere til offentlige / echo.js.

Ja, jeg forstår, det er litt overkill for bare å få en enkelt JavaScript-fil. Hvis du ikke vil gå gjennom denne øvelsen, kan du laste ned echo.js fil fra min GitHub.

Og med det, er vi ferdige med installasjonen av klientbibliotekene våre.

Back-End File Setup

Husk at vi snakket om å sette opp et program som tillater brukere av applikasjonen å sende meldinger til hverandre. På den annen side sender vi kringkastingsvarsler til brukere som er logget inn når de mottar en ny melding fra andre brukere.

I denne delen skal vi opprette filene som kreves for å implementere brukskassen som vi leter etter.

Til å begynne med, la oss lage Budskap modell som holder meldinger sendt av brukere til hverandre.

$ php artisan make: modell melding - migrasjon

Vi må også legge til noen få felt som til, fra og budskap til vårt meldingsbord. Så la oss endre migreringsfilen før du kjører overfør kommandoen.

trinn ( 'id'); $ table-> heltall ('fra', FALSE, SANT); $ tabell-> heltall ('til', feil, sant); $ Tabell-> tekst ( 'melding'); $ Tabell-> tidsstempler (); );  / ** * Omvendt migrasjonene. * * @return void * / offentlig funksjon ned () Schema :: dropIfExists ('messages'); 

La oss nå kjøre kommandoen Migrere som lager meldingsbordet i databasen.

$ php håndverk migrere

Når du vil hente en tilpasset begivenhet i Laravel, bør du opprette en klasse for den hendelsen. Basert på type arrangement, reagerer Laravel tilsvarende og tar nødvendige tiltak.

Hvis hendelsen er en vanlig hendelse, kaller Laravel de tilhørende lytteklassene. På den annen side, hvis hendelsen er av sendetype, sender Laravel den hendelsen til web-socket-serveren som er konfigurert i config / broadcasting.php fil.

Når vi bruker Pusher-tjenesten i vårt eksempel, sender Laravel hendelser til Pusher-serveren.

La oss bruke følgende artisan-kommando for å lage en tilpasset hendelsesklasse-NewMessageNotification.

$ php artisan make: event NewMessageNotification

Det burde skape app / Events / NewMessageNotification.php klasse. La oss erstatte innholdet til den filen med følgende.

melding = $ melding;  / ** * Få kanalene hendelsen skal kringkaste på. * * @return Channel | array * / public function broadcastOn () returnere nye PrivateChannel ('user.'. $ this-> message-> to); 

Det viktige å merke seg er at NewMessageNotification klassen implementerer ShouldBroadcastNow grensesnitt. Når vi hevder et arrangement, vet Laravel at denne hendelsen skal sendes.

Faktisk kan du også implementere ShouldBroadcast grensesnitt, og Laravel legger til en hendelse i hendelseskøen. Den blir behandlet av hendelsen køar arbeideren når det får en sjanse til å gjøre det. I vårt tilfelle ønsker vi å kringkaste det med en gang, og det er derfor vi har brukt ShouldBroadcastNow grensesnitt.

I vårt tilfelle ønsker vi å vise en melding brukeren har mottatt, og dermed har vi passert Budskap modell i konstruktørargumentet. På denne måten blir dataene sendt sammen med arrangementet.

Deretter er det broadcastOn Metode som definerer navnet på kanalen som arrangementet vil bli kringkastet. I vårt tilfelle har vi brukt den private kanalen da vi vil begrense hendelsessendingen til innloggede brukere.

De $ Dette->-melding> til variabel refererer til IDen til brukeren som hendelsen vil bli kringkastet. Dermed gjør det effektivt kanalnavnet som brukeren. USER_ID.

Når det gjelder private kanaler, må klienten autentisere seg selv før det etableres en forbindelse med web-socket-serveren. Det sørger for at hendelser som sendes på private kanaler, kun sendes til godkjente klienter. I vårt tilfelle betyr det at kun innloggede brukere vil kunne abonnere på kanalen vår brukeren. USER_ID.

Hvis du bruker Laravel Echo-klientbiblioteket for kanalabonnement, har du lykke til! Det tar seg automatisk av autentiseringsdelen, og du må bare definere kanalruter.

La oss gå videre og legge til en rute for vår private kanal i ruter / channels.php fil.

id === (int) $ id; ); Broadcast :: channel ('user. ToUserId', funksjon ($ bruker, $ toUserId) return $ user-> id == $ toUserId;);

Som du kan se, har vi definert brukeren. toUserId rute for vår private kanal.

Det andre argumentet i kanalmetoden bør være en lukkefunksjon. Laravel sender automatisk den innloggede brukeren som det første argumentet for lukkingsfunksjonen, og det andre argumentet hentes vanligvis fra kanalnavnet.

Når klienten prøver å abonnere på den private kanalen brukeren. USER_ID, Laravel Echo-biblioteket gjør nødvendig verifisering i bakgrunnen ved hjelp av XMLHttpRequest-objektet, eller mer kjent som XHR.

Så langt er vi ferdige med oppsettet, så la oss gå videre og teste det.

Front-End File Setup

I denne delen lager vi filene som kreves for å teste bruksvesenet.

La oss gå videre og opprette en kontrollerfil på app / Http / kontrollere / MessageController.php med følgende innhold.

mellomvare ( 'aut');  offentlig funksjon indeks () $ user_id = Auth :: bruker () -> id; $ data = array ('user_id' => $ user_id); returnere visning ("broadcast", $ data);  offentlig funksjon send () // ... // meldingen blir sendt $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo melding fra bruker 1 til bruker 2'); $ Melding-> Lagre (); // ønsker å kringkaste NewMessageNotification hendelsesbegivenhet (ny NewMessageNotification ($ message)); // ...

I index metode, bruker vi kringkaste se, så la oss lage ressurser / visninger / broadcast.blade.php se også fil.

        Test     
Ny varsel blir varslet i sanntid!

Og selvfølgelig må vi legge til ruter også i ruter / web.php fil.

Rute :: få ('melding / indeks', 'MessageController @ index'); Rute :: få ('melding / send', 'MessageController @ send');

I konstruktørmetoden til kontrollerklassen kan du se at vi har brukt auth mellomvare for å sikre at kontrolleringsmetoder bare er tilgjengelige av innloggede brukere.

Deretter er det index metode som gjør kringkaste utsikt. La oss trekke inn den viktigste koden i visningsfilen.

    

For det første laster vi de nødvendige klientbibliotekene, Laravel Echo og Pusher, slik at vi kan åpne nettkontakten til Pusher web-socket server.

Deretter oppretter vi forekomsten av ekko ved å gi Pusher som vår kringkastingsadapter og annen nødvendig Pusher-relatert informasjon.

Når vi går videre, bruker vi den private metoden Echo til å abonnere på den private kanalen brukeren. USER_ID. Som vi diskuterte tidligere må klienten autentisere seg selv før du abonnerer på den private kanalen. Dermed Ekko objekt utfører nødvendig godkjenning ved å sende XHR i bakgrunnen med nødvendige parametere. Endelig forsøker Laravel å finne brukeren. USER_ID rute, og den skal samsvare med ruten som vi har definert i ruter / channels.php fil.

Hvis alt går bra, bør du ha en nettkontaktforbindelse åpen med Pusher web-socket-serveren, og det er oppført hendelser på brukeren. USER_ID kanal! Fra nå av kan vi motta alle innkommende hendelser på denne kanalen.

I vårt tilfelle vil vi lytte etter NewMessageNotification arrangement og dermed har vi brukt lytte metode av Ekko motsette seg å oppnå det. For å holde ting enkelt, vil vi bare varsle meldingen som vi har mottatt fra Pusher-serveren.

Så det var oppsettet for å motta hendelser fra web-sockets-serveren. Deretter går vi gjennom sende metode i kontrollerfilen som hevder sendingshendelsen.

La oss raskt trekke inn koden til sende metode.

offentlig funksjon send () // ... // meldingen blir sendt $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo melding fra bruker 1 til bruker 2'); $ Melding-> Lagre (); // ønsker å kringkaste NewMessageNotification hendelsesbegivenhet (ny NewMessageNotification ($ message)); // ...

I vårt tilfelle skal vi varsle innloggede brukere når de mottar en ny melding. Så vi har forsøkt å etterligne den oppførselen i sende metode.

Deretter har vi brukt begivenhet hjelperfunksjon for å heve NewMessageNotification begivenhet. Siden NewMessageNotification hendelsen er av ShouldBroadcastNow type, Laravel laster standard kringkastingskonfigurasjon fra config / broadcasting.php fil. Endelig sender den ut NewMessageNotification hendelse til den konfigurerte nettstikkserveren på brukeren. USER_ID kanal.

I vårt tilfelle vil arrangementet sendes til Pusher web-socket server på brukeren. USER_ID kanal. Hvis mottakerens bruker er ID 1, arrangementet vil bli kringkastet over user.1 kanal.

Som vi diskuterte tidligere, har vi allerede et oppsett som lytter til hendelser på denne kanalen, så det skal kunne motta denne hendelsen, og varslingsboksen vises til brukeren!

La oss gå videre og gå gjennom hvordan du skal teste bruksområdet som vi har bygget så langt.

Åpne URL http: // din-laravel-site-domain / message / index i nettleseren din. Hvis du ikke er logget inn enda, blir du omdirigert til påloggingsskjermen. Når du er logget inn, bør du se kringkastingsvisningen som vi tidligere har definert, ikke noe fancy enda.

Faktisk har Laravel gjort litt arbeid i bakgrunnen allerede for deg. Som vi har aktivert Pusher.logToConsole Innstilling levert av Pusher-klientbiblioteket, logger det alt i nettleserkonsollen for feilsøkingsformål. La oss se hva som blir logget på konsollen når du åpner http: // din-laravel-site-domene / melding / indeksside.

Pusher: Status endret: initialisert -> koble Pusher: Koble til: "transport": "ws", "url": "wss: //ws-ap2.pusher.com: 443 / app / c91c1b7e8c6ece46053b? Protokoll = 7 & klient = js og versjon = 4.1.0 & flash = false " Pusher: Koble til: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Pusher: Status endret: tilkobling -> koblet til nytt stikkontakt ID 1386.68660 Pusher: Event sendt: " event ":" pusher: subscribe "," data ": " auth ":" c91c1b7e8c6ece46053b: cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d "," kanal ":" privatbruker.2 " Pusher: Event recd: " event ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" privatbruker.2 " Pusher: Ingen tilbakeringinger på privatbruker.2 for pusher: subscription_succeeded

Den har åpnet nettkontaktforbindelsen med Pusher web-socket serveren og abonnerer på å lytte til hendelser på den private kanalen. Selvfølgelig kan du ha et annet kanalnavn i ditt tilfelle basert på IDen til brukeren du er logget på med. La oss nå holde denne siden åpen når vi flytter for å teste sende metode.

Deretter la vi åpne http: // din-laravel-site-domene / melding / send URL på den andre kategorien eller i en annen nettleser. Hvis du skal bruke en annen nettleser, må du logge inn for å kunne få tilgang til den aktuelle siden.

Så snart du åpner http: // din-laravel-site-domene / melding / send side, bør du kunne se en varselmelding i den andre kategorien på http: // din-laravel-site-domene / melding / index.

La oss navigere til konsollen for å se hva som nettopp har skjedd.

Pusher: Event recd: "event": "App \\ Events \\ NewMessageNotification", "data": "melding": "id": 57, "fra": 1, "til": 2, "melding ":" Demo melding fra bruker 1 til bruker 2 "," created_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 "," kanal ":" privat-user.2" 

Som du kan se, forteller det deg at du nettopp har mottatt App \ Hendelser \ NewMessageNotification hendelse fra Pusher web-socket server på privat-user.2 kanal.

Faktisk kan du se hva som skjer der ute på Pusher-enden også. Gå til Pusher-kontoen din og naviger til søknaden din. Under Debug Console, Du bør kunne se meldinger som logges.

Og det bringer oss til slutten av denne artikkelen! Forhåpentligvis var det ikke for mye på en gang, da jeg har forsøkt å forenkle ting etter mitt beste.

Konklusjon

I dag gikk vi gjennom en av de minst diskuterte funksjonene til Laravel-kringkasting. Det lar deg sende sanntidsmeldinger ved hjelp av webkontakter. Gjennom hele denne artikkelen har vi bygget et ekteeksempel som demonstrerte det ovennevnte konseptet.

.