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.
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.
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.
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.
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å.
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.
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.
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.
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.
.