Hur Laravel Broadcasting fungerar

Idag kommer vi att undersöka konceptet kring sändning i Laravel webs ramverk. Det låter dig skicka meddelanden till klientsidan när något händer på serverns sida. I den här artikeln kommer vi att använda det tredje partens Pusher-bibliotek för att skicka meddelanden till klientsidan.

Om du någonsin velat skicka meddelanden från servern till kunden när något händer på en server i Laravel, letar du efter sändningsfunktionen.

Anta till exempel att du har implementerat en meddelandeprogram som tillåter användare av ditt system att skicka meddelanden till varandra. Nu, då användaren A skickar ett meddelande till användaren B, vill du meddela användaren B i realtid. Du kan visa en popup- eller en varningsruta som informerar användaren B om det nya meddelandet!

Det är det perfekta användningsfallet att gå igenom begreppet sändning i Laravel, och det är vad vi ska genomföra i den här artikeln.

Om du undrar hur servern kan skicka meddelanden till klienten använder den uttag under huven för att uppnå det. Låt oss förstå det grundläggande flödet av uttag innan vi dyker djupare in i själva genomförandet.

  • För det första behöver du en server som stöder protokollet för webbuttag och gör att klienten kan upprätta en webbanslutning.
  • Du kan implementera din egen server eller använda en tjänst från tredje part som Pusher. Vi föredrar den senare i den här artikeln.
  • Klienten initierar en webbkontaktanslutning till webbkontakten och får en unik identifierare vid en lyckad anslutning.
  • När anslutningen har lyckats, abonnerar klienten på vissa kanaler där den vill ta emot händelser.
  • Slutligen registrerar kunden händelser som den lyssnar på under den prenumererade kanalen.
  • Nu på serverns sida, när en viss händelse inträffar, informerar vi webben-servern genom att ge den med kanalnamnet och händelsens namn.
  • Slutligen sänder webben-servern den händelsen till registrerade kunder på den specifika kanalen.

Oroa dig inte om det ser ut som för mycket på en enda gång; du kommer att hänga på det när vi flyttar igenom den här artikeln.

Låt oss nu titta på standardutsändningskonfigurationsfilen på config / broadcasting.php.

 env ('BROADCAST_DRIVER', 'logg'), / * | ------------------------------------ -------------------------------------- | Broadcast Connections | ----------------------------------------------- --------------------------- | | Här kan du definiera alla sändningsanslutningar som ska användas | att sända händelser till andra system eller över websockets. Prov av | varje tillgänglig typ av anslutning tillhandahålls inuti denna array. | * / 'connections' => ['drivrutin' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'hemlig' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID')], 'redis' => ['drivrutin' => 'redis', 'connection' => 'default',], 'log' => ['drivrutin' => 'logg ',],' null '=> [' drivrutin '=>' null ',],],];

Som standard stöder Laravel flera sändningsadaptrar i själva kärnan.

I den här artikeln kommer vi att använda Langare sändningsadapter. För debugging ändamål kan du också använda loggadaptern. Självklart, om du använder logga Adaptern kommer inte klienten att få några händelseanmälningar, och det kommer bara att loggas till laravel.log fil.

Från nästa avsnitt framåt kommer vi genast att dyka in i det faktiska genomförandet av ovannämnda användningsfall.

Ställa in förutsättningarna

I sändningen finns det olika typer av kanaler - offentliga, privata och närvaro. När du vill sända dina händelser offentligt är det den offentliga kanalen som du ska använda. Omvänt används den privata kanalen när du vill begränsa händelseanmälningar till vissa privata kanaler.

I vårt användningsfall vill vi meddela användare när de får ett nytt meddelande. Och för att vara berättigad att ta emot sändningsanmälningar måste användaren vara inloggad. Således måste vi använda den privata kanalen i vårt fall.

Kärnautentiseringsfunktion

För det första måste du aktivera standard Laravel-autentiseringssystemet så att funktioner som registrering, inloggning och liknande fungerar ut ur rutan. Om du inte är säker på hur du gör det, ger den officiella dokumentationen en snabb inblick i det.

Pusher SDK-installation och konfiguration

Som vi ska använda Langare Tjänsten från tredje part som vår webbserver, måste du skapa ett konto med det och se till att du har nödvändiga API-uppgifter med din postregistrering. Om du står inför några problem med att skapa det, tveka inte att fråga mig i kommentarsektionen.

Därefter måste vi installera Pusher PHP SDK så att vår Laravel-applikation kan skicka sända meddelanden till Pusher web-socket-servern.

I din Laravel-programrots, kör följande kommando för att installera det som ett kompositörspaket.

$ komponent kräver pusher / pusher-php-server "~ 3.0"

Låt oss nu ändra sändningskonfigurationsfilen för att aktivera Pusher-adaptern som standard sändardrivrutin.

 env ('BROADCAST_DRIVER', 'pusher'), / * | ------------------------------------ -------------------------------------- | Broadcast Connections | ----------------------------------------------- --------------------------- | | Här kan du definiera alla sändningsanslutningar som ska användas | att sända händelser till andra system eller över websockets. Prov av | varje tillgänglig typ av anslutning tillhandahålls inuti denna array. | * / 'connections' => ['drivrutin' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'hemlig' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'options' => ['cluster' => 'ap2', 'krypterat' => sant],], 'redis' => ['drivrutin' => 'redis' anslutning '=>' standard ',],' log '=> [' drivrutin '=>' logg ',],' null '=> [' drivrutin '=>' null ',],]

Som du kan se har vi ändrat standard sändardrivrutinen till Pusher. Vi har också lagt till kluster och krypterade konfigurationsalternativ som du borde ha fått från Pusher-kontot i första hand.

Det hämtar också värden från miljövariabler. Så låt oss se till att vi ställer in följande variabler i .env filen korrekt.

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

Därefter var jag tvungen att göra några ändringar i ett par centrala Laravel-filer för att göra den kompatibel med den senaste Pusher SDK. Självklart rekommenderar jag inte att göra några ändringar i kärnramen, men jag ska bara markera vad som behöver göras.

Gå vidare och öppna leverantör / laravel / ram / src / Illuminate / Broadcasting / Broadcasters / PusherBroadcaster.php fil. Byt ut bara snippet använd Pusher; med använd Pusher \ Pusher;.

Låt oss sedan öppna leverantör / laravel / ram / src / Illuminate / Broadcasting / BroadcastManager.php fil och gör en liknande ändring i följande kod.

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

Till sist, låt oss aktivera sändningstjänsten i config / app.php genom att ta bort kommentaren i följande rad.

App \ Providers \ BroadcastServiceProvider :: klass,

Hittills har vi installerat serverns specifika bibliotek. I nästa avsnitt går vi igenom klientbibliotek som måste installeras också.

Pusher and Laravel Echo Libraries-Installation och konfiguration

Vid sändning är kundens ansvar att prenumerera på kanaler och lyssna på önskade händelser. Under huven gör den den genom att öppna en ny anslutning till webb-socket-servern.

Lyckligtvis behöver vi inte implementera några komplexa JavaScript-saker för att uppnå det, eftersom Laravel redan tillhandahåller ett användbart klientbibliotek, Laravel Echo, som hjälper oss att hantera uttag på klientsidan. Det stöder också Pusher-tjänsten som vi ska använda i den här artikeln.

Du kan installera Laravel Echo med hjälp av NPM-pakethanteraren. Självklart måste du installera nod och npm i första hand om du inte redan har dem. Resten är ganska enkel, som visas i följande kod.

$ npm installera laravel-echo

Det vi är intresserade av är node_modules / laravel-eko / dist / echo.js fil som du ska kopiera till offentliga / echo.js.

Ja, jag förstår, det är lite överkill för att bara få en enda JavaScript-fil. Om du inte vill gå igenom den här övningen kan du ladda ner echo.js filen från min GitHub.

Och med det är vi färdiga med installationen av våra kundbibliotek.

Back-End File Setup

Kom ihåg att vi pratade om att skapa en applikation som tillåter användare av vår ansökan att skicka meddelanden till varandra. Å andra sidan skickar vi sändningsanmälningar till användare som är inloggade när de får ett nytt meddelande från andra användare.

I det här avsnittet skapar vi de filer som krävs för att implementera användningsfallet som vi letar efter.

Till att börja med, låt oss skapa Meddelande modell som innehåller meddelanden som skickas av användare till varandra.

$ php artisan make: modell meddelande - migration

Vi måste också lägga till några fält som till, från och meddelande till vår meddelandetabell. Så låt oss ändra migrationsfilen innan du kör kommandot migrera.

inkrement ( 'id'); $ table-> heltal ('from', FALSE, TRUE); $ tabell-> heltal ('till', felaktigt, sant); $ Bords> text (meddelande '); $ Tabell-> tidsstämplar (); );  / ** * Omvandla migrationerna. * * @return void * / public function down () Schema :: dropIfExists ('messages'); 

Nu, låt oss köra kommandot migrera som skapar meddelandetabellen i databasen.

$ php hantverkare migrera

När du vill hämta en anpassad händelse i Laravel ska du skapa en klass för den händelsen. Baserat på typen av händelse, reagerar Laravel i enlighet därmed och vidtar nödvändiga åtgärder.

Om händelsen är en vanlig händelse, samtalar Laravel de associerade lyssnarklasserna. Å andra sidan, om händelsen är av sändningstyp, skickar Laravel den händelsen till webbsajtservern som är konfigurerad i config / broadcasting.php fil.

När vi använder Pusher-tjänsten i vårt exempel skickar Laravel händelser till Pusher-servern.

Låt oss använda följande artisan kommando för att skapa en anpassad händelseklass-NewMessageNotification.

$ php artisan make: händelse NewMessageNotification

Det borde skapa app / Events / NewMessageNotification.php klass. Låt oss ersätta innehållet i den filen med följande.

meddelande = $ meddelande;  / ** * Hämta kanalerna som händelsen ska sända på. * * @return Channel | array * / public function broadcastOn () returnera nya PrivateChannel ('user.'. $ this-> message-> to); 

Det viktiga att notera är att NewMessageNotification klassen implementerar ShouldBroadcastNow gränssnitt. När vi väcker en händelse, vet Laravel att den här händelsen ska sändas.

Faktum är att du också kan implementera ShouldBroadcast gränssnitt, och Laravel lägger till en händelse i evenemangskön. Det kommer att behandlas av evenemangsköare när det blir en chans att göra det. I vårt fall vill vi sända det direkt, och det är därför vi har använt ShouldBroadcastNow gränssnitt.

I vårt fall vill vi visa ett meddelande som användaren har fått, och sålunda har vi passerat Meddelande modell i konstruktörargumentet. På så sätt kommer data att skickas tillsammans med händelsen.

Därefter finns det broadcastOn metod som definierar namnet på den kanal som händelsen kommer att sändas på. I vårt fall har vi använt den privata kanalen eftersom vi vill begränsa händelsessändningen till inloggade användare.

De $ This-> meddelande-> till variabel hänvisar till användarens ID till vilken händelsen kommer att sändas. Således gör det effektivt kanalnamnet som användare. USER_ID.

När det gäller privata kanaler måste klienten autentisera sig innan du etablerar en anslutning till webbutgångsservern. Det säkerställer att händelser som sänds på privata kanaler skickas endast till autentiserade klienter. I vårt fall betyder det att endast inloggade användare kommer att kunna prenumerera på vår kanal användare. USER_ID.

Om du använder Laravel Echo-klientbiblioteket för kanalabonnemang har du lycka till! Det tar automatiskt hand om autentiseringsdelen, och du behöver bara definiera kanalrutterna.

Låt oss fortsätta och lägga till en rutt för vår privata kanal i rutter / channels.php fil.

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

Som du kan se har vi definierat användare. toUserId rutt för vår privata kanal.

Kanalmetodens andra argument bör vara en stängningsfunktion. Laravel skickar automatiskt in den inloggade användaren som det första argumentet för stängningsfunktionen, och det andra argumentet hämtas vanligtvis från kanalnamnet.

När klienten försöker prenumerera på den privata kanalen användare. USER_ID, Laravel Echo-biblioteket gör den nödvändiga autentiseringen i bakgrunden med hjälp av XMLHttpRequest-objektet, eller mer känt som XHR.

Hittills har vi slutat med installationen, så låt oss fortsätta och testa det.

Front-End File Setup

I det här avsnittet skapar vi de filer som krävs för att testa vårt användningsfall.

Låt oss fortsätta och skapa en kontrollerfil på app / HTTP / Controllers / MessageController.php med följande innehåll.

middleware ( 'auth');  offentliga funktionsindex () $ user_id = Auth :: user () -> id; $ data = array ('user_id' => $ user_id); returnera vy ("broadcast", $ data);  public function send () // ... // meddelandet skickas $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo meddelande från användare 1 till användare 2'); $ Meddelande-> Spara (); // vill sända NewMessageNotification event händelse (ny NewMessageNotification ($ message)); // ...

I index metod använder vi utsända visa, så låt oss skapa resurser / views / broadcast.blade.php visa fil också.

        Testa     
Ny anmälan kommer att varas i realtid!

Och naturligtvis måste vi också lägga till rutter i rutter / web.php fil.

Rutt :: få ('meddelande / index', 'MessageController @ index'); Rutt :: få ("meddelande / skicka", "MessageController @ send");

I konstruktormetoden i kontrollerklassen kan du se att vi har använt auth middleware för att se till att regleringsmetoder endast är åtkomliga av inloggade användare.

Därefter finns det index metod som gör utsända se. Låt oss dra in den viktigaste koden i visningsfilen.

    

För det första laddar vi de nödvändiga klientbibliotek, Laravel Echo och Pusher, så att vi kan öppna webbanslutningen till Pusher web-socket-servern.

Därefter skapar vi förekomsten av Echo genom att tillhandahålla Pusher som vår sändningsadapter och annan nödvändig Pusher-relaterad information.

När vi går vidare använder vi den privata metoden för Echo för att prenumerera på den privata kanalen användare. USER_ID. Som vi diskuterade tidigare måste klienten autentisera sig innan du prenumererar på den privata kanalen. Således Eko objekt utför den nödvändiga autentiseringen genom att skicka XHR i bakgrunden med nödvändiga parametrar. Slutligen försöker Laravel att hitta användare. USER_ID rutt, och den ska matcha den rutt som vi har definierat i rutter / channels.php fil.

Om allt går bra borde du ha en webbkontaktanslutning öppen med Pusher web-socket-servern, och det listar händelser på användare. USER_ID kanalisera! Från och med nu kan vi ta emot alla inkommande händelser på den här kanalen.

I vårt fall vill vi lyssna på NewMessageNotification händelse och sålunda har vi använt lyssna metod för Eko föremål för att uppnå det. För att hålla sakerna enkla, kommer vi bara att varna det meddelande som vi har fått från Pusher-servern.

Så det var installationen för att ta emot händelser från web-sockets-servern. Därefter går vi igenom skicka metod i kontrollerfilen som höjer sändningsevenemanget.

Låt oss snabbt dra in koden för skicka metod.

public function send () // ... // meddelandet skickas $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo meddelande från användare 1 till användare 2'); $ Meddelande-> Spara (); // vill sända NewMessageNotification event händelse (ny NewMessageNotification ($ message)); // ...

I vårt fall kommer vi att meddela inloggade användare när de får ett nytt meddelande. Så vi har försökt att efterlikna det beteendet i skicka metod.

Därefter har vi använt händelse hjälparfunktion för att höja NewMessageNotification händelse. Sedan NewMessageNotification händelsen är av ShouldBroadcastNow typ laddar Laravel standard sändningskonfigurationen från config / broadcasting.php fil. Slutligen sänder den NewMessageNotification händelse till den konfigurerade webbkontakten på användare. USER_ID kanalisera.

I vårt fall kommer evenemanget att sändas till Pusher web-socket-servern på användare. USER_ID kanalisera. Om mottagarens användarens ID är 1, evenemanget kommer att sändas över user.1 kanalisera.

Som vi diskuterade tidigare har vi redan en inställning som lyssnar på händelser på den här kanalen, så den borde kunna ta emot den här händelsen och varningsrutan visas till användaren!

Låt oss fortsätta och gå igenom hur du ska testa det användningsfall som vi hittills har byggt.

Öppna URL http: // your-laravel-site-domain / message / index i din webbläsare. Om du inte är inloggad än, kommer du vidarebefordras till inloggningsskärmen. När du är inloggad bör du se den sändningsvy som vi definierade tidigare, ingenting som vi än vill ha.

I själva verket har Laravel gjort en hel del arbete i bakgrunden redan för dig. Som vi har aktiverat Pusher.logToConsole inställning som tillhandahålls av Pusher-klientbiblioteket loggar det allt i webbläsarkonsolen för felsökningsändamål. Låt oss se vad som loggas till konsolen när du öppnar http: // din-laravel-webbplats-domänen / meddelandet / indexsidan.

Pusher: Status ändrad: initialiserad -> anslutning Pusher: Anslutande: "transport": "ws", "url": "wss: //ws-ap2.pusher.com: 443 / app / c91c1b7e8c6ece46053b? Protokoll = 7 & klient = js & version = 4.1.0 & flash = false " Pusher: Anslutning: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Pusher: Status ändrad: anslutning -> ansluten till nytt uttag ID 1386.68660 Pusher: Händelse skickad: " händelse ":" pusher: subscribe "," data ": " auth ":" c91c1b7e8c6ece46053b: cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d "," kanal ":" privat-användare.2 " Pusher: Event recd: " händelse ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" privat-användare.2 " Pusher: Inga återuppringningar på privat-användare.2 för pusher: subscription_succeeded

Den har öppnat webbanslutningen med Pusher web-socket-servern och prenumererade på att lyssna på händelser på den privata kanalen. Naturligtvis kan du ha ett annat kanalnamn i ditt fall baserat på användarens ID som du är inloggad med. Nu, låt oss hålla den här sidan öppen när vi flyttar för att testa skicka metod.

Låt oss sedan öppna http: // din-laravel-webbplats-domänen / meddelandet / skicka URL-adressen på den andra fliken eller i en annan webbläsare. Om du ska använda en annan webbläsare måste du logga in för att kunna komma åt den sidan.

Så fort du öppnar http: // din-laravel-webbplats-domänen / meddelandet / sändningssidan, bör du kunna se ett varningsmeddelande på den andra fliken på http: // din-laravel-webbplats-domän / meddelande /index.

Låt oss navigera till konsolen för att se vad som just har hänt.

Pusher: Event recd: "event": "App \\ Events \\ NewMessageNotification", "data": "message": "id": 57, "från": 1, "till": 2, "meddelande ":" Demo meddelande från användare 1 till användare 2 "," created_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 "," kanal ":" privata user.2" 

Som du kan se, berättar det för dig att du just fått App \ Events \ NewMessageNotification händelse från Pusher web-socket server på privata user.2 kanalisera.

Faktum är att du kan se vad som händer där ute hos Pusher-änden. Gå till ditt Pusher konto och navigera till din ansökan. Under debug Trösta, Du borde kunna se meddelanden som loggas.

Och det leder oss till slutet av denna artikel! Förhoppningsvis var det inte för mycket på ett och samma sätt som jag har försökt att förenkla sakerna så vitt jag vet.

Slutsats

Idag gick vi igenom en av de minst diskuterade funktionerna i Laravel-sändningen. Det låter dig skicka meddelanden i realtid med hjälp av webbuttag. Under hela den här artikeln byggde vi ett verkligt exempel som visade det ovan nämnda konceptet.

.