Hoe Laravel Broadcasting werkt

Vandaag gaan we het concept van uitzending verkennen in het Laravel-webraamwerk. Hiermee kunt u meldingen naar de client verzenden wanneer er iets gebeurt aan de serverzijde. In dit artikel gaan we de Pusher-bibliotheek van derden gebruiken om meldingen naar de client te verzenden.

Als u ooit meldingen van de server naar de client wilt verzenden wanneer er iets gebeurt op een server in Laravel, zoekt u de uitzendfunctie.

Laten we bijvoorbeeld aannemen dat u een berichtentoepassing hebt geïmplementeerd waarmee gebruikers van uw systeem berichten naar elkaar kunnen verzenden. Wanneer gebruiker A een bericht verzendt naar gebruiker B, wilt u gebruiker B in realtime op de hoogte stellen. U kunt een pop-upvenster of waarschuwingsvenster weergeven dat gebruiker B informeert over het nieuwe bericht!

Het is de perfecte use-case om door het concept van uitzending in Laravel te lopen, en dat is wat we in dit artikel zullen implementeren.

Als je je afvraagt ​​hoe de server berichten naar de client kan verzenden, gebruikt het sockets onder de motorkap om het te bereiken. Laten we de basisstroom van sockets begrijpen voordat we dieper ingaan op de daadwerkelijke implementatie.

  • Ten eerste hebt u een server nodig die het protocol voor web-sockets ondersteunt en waarmee de client een websocket-verbinding tot stand kan brengen.
  • U kunt uw eigen server implementeren of een service van derden zoals Pusher gebruiken. We geven de voorkeur aan de laatste in dit artikel.
  • De client start een web socket-verbinding met de web socket-server en ontvangt een unieke identifier na succesvolle verbinding.
  • Zodra de verbinding succesvol is, abonneert de client zich op bepaalde kanalen waarop hij evenementen wil ontvangen.
  • Ten slotte registreert de client onder het kanaal waarop is geabonneerd gebeurtenissen waarnaar hij zou willen luisteren.
  • Nu aan de serverzijde, wanneer een bepaalde gebeurtenis plaatsvindt, informeren we de websocketserver door deze de kanaalnaam en evenementnaam te geven.
  • En ten slotte zendt de websocket-server die gebeurtenis uit naar geregistreerde clients op dat specifieke kanaal.

Maak je geen zorgen als het er in één keer te veel uitziet; je zult het onder de knie krijgen terwijl we door dit artikel gaan.

Laten we nu eens kijken naar het standaard broadcast-configuratiebestand op config / broadcasting.php.

 env ('BROADCAST_DRIVER', 'log'), / * | ------------------------------------ -------------------------------------- | Broadcast-verbindingen | ----------------------------------------------- --------------------------- | | Hier kunt u alle uitzendingsverbindingen definiëren die zullen worden gebruikt | om evenementen naar andere systemen of via websockets uit te zenden. Voorbeelden van | elk beschikbaar type verbinding wordt in deze array geleverd. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'key' => 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 ',],],];

Standaard ondersteunt Laravel meerdere broadcast-adapters in de kern zelf.

In dit artikel gaan we de gebruiken Pusher uitzendadapter. Voor foutopsporingsdoeleinden kunt u ook de logboekadapter gebruiken. Natuurlijk, als u de logboek adapter, ontvangt de client geen gebeurtenismeldingen en wordt deze alleen bij de laravel.log het dossier.

Vanaf het volgende deel duiken we meteen in op de daadwerkelijke implementatie van de bovengenoemde use-case.

De vereisten instellen

Bij uitzendingen zijn er verschillende soorten kanalen: openbaar, privé en aanwezigheid. Wanneer u uw evenementen publiekelijk wilt uitzenden, is dit het openbare kanaal dat u hoort te gebruiken. Omgekeerd wordt het privékanaal gebruikt wanneer u gebeurtenismeldingen wilt beperken tot bepaalde privé-kanalen.

In onze gebruikssituatie willen we gebruikers op de hoogte stellen wanneer ze een nieuw bericht ontvangen. En om in aanmerking te komen voor het ontvangen van broadcastmeldingen, moet de gebruiker zijn aangemeld. We moeten dus het privékanaal gebruiken in ons geval.

Core Authentication Feature

Ten eerste moet u het standaard Laravel-authenticatiesysteem inschakelen zodat functies zoals registratie, login en dergelijke direct uit de doos werken. Als u niet zeker weet hoe u dat moet doen, biedt de officiële documentatie een snel inzicht daarin.

Pusher SDK-installatie en configuratie

Omdat we het gaan gebruiken Pusher service van derden als onze websocketserver, moet u er een account bij maken en moet u ervoor zorgen dat u de nodige API-inloggegevens bij uw postregistratie hebt. Als je problemen ondervindt bij het maken ervan, aarzel dan niet om het mij te vragen in het gedeelte met reacties.

Vervolgens moeten we de Pusher PHP SDK installeren zodat onze Laravel-applicatie broadcastmeldingen kan verzenden naar de Pusher web-socket server.

Voer in de Laravel-toepassing de volgende opdracht uit om het als een compositiepakket te installeren.

$ composer vereist push / pusher-php-server "~ 3.0"

Laten we nu het uitzendconfiguratiebestand wijzigen om de Pusher-adapter in te schakelen als ons standaard broadcaststuurprogramma.

 env ('BROADCAST_DRIVER', 'pusher'), / * | ------------------------------------ -------------------------------------- | Broadcast-verbindingen | ----------------------------------------------- --------------------------- | | Hier kunt u alle uitzendingsverbindingen definiëren die zullen worden gebruikt | om evenementen naar andere systemen of via websockets uit te zenden. Voorbeelden van | elk beschikbaar type verbinding wordt in deze array geleverd. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'secret' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'options' => ['cluster' => 'ap2', 'encryption' => true],], 'redis' => ['driver' => 'redis', ' verbinding '=>' standaard ',],' log '=> [' driver '=>' log ',],' null '=> [' driver '=>' null ',],],];

Zoals u kunt zien, hebben we het standaard broadcast-stuurprogramma gewijzigd in Pusher. We hebben ook cluster- en gecodeerde configuratie-opties toegevoegd die u in eerste instantie had moeten hebben van het Pusher-account.

Het haalt ook waarden van omgevingsvariabelen op. Dus laten we ervoor zorgen dat we de volgende variabelen instellen in de .env bestand correct.

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

Vervolgens moest ik een paar kern Laravel-bestanden wijzigen om het compatibel te maken met de nieuwste Pusher SDK. Natuurlijk raad ik aan om geen wijzigingen aan te brengen in het kernraamwerk, maar ik zal alleen even benadrukken wat er moet gebeuren.

Ga je gang en open de verkoper / laravel / framework / src / Illuminate / Broadcasting / Omroepen / PusherBroadcaster.php het dossier. Vervang gewoon het fragment gebruik Pusher; met gebruik Pusher \ Pusher;.

Laten we vervolgens de. Openen verkoper / laravel / framework / src / Illuminate / Broadcasting / BroadcastManager.php bestand en breng een soortgelijke wijziging aan in het volgende fragment.

retourneer nieuwe PusherBroadcaster (nieuwe \ Pusher \ Pusher ($ config ['key'], $ config ['secret'], $ config ['app_id'], Arr :: get ($ config, 'options', [])) );

Laten we tot slot de uitzenddienst inschakelen in config / app.php door de opmerking in de volgende regel te verwijderen.

App \ Providers \ BroadcastServiceProvider :: klasse,

Tot nu toe hebben we serverspecifieke bibliotheken geïnstalleerd. In de volgende sectie gaan we door clientbibliotheken die ook moeten worden geïnstalleerd.

Pusher en Laravel Echo-bibliotheken - Installatie en configuratie

Bij het uitzenden is de verantwoordelijkheid van de cliëntkant om zich te abonneren op kanalen en naar gewenste gebeurtenissen te luisteren. Onder de motorkap wordt dit bereikt door een nieuwe verbinding met de websocketserver te openen.

Gelukkig hoeven we geen complexe JavaScript-dingen te implementeren om dit te bereiken, aangezien Laravel al een bruikbare clientbibliotheek biedt, Laravel Echo, die ons helpt om sockets aan de kant van de klant aan te pakken. Het ondersteunt ook de Pusher-service die we in dit artikel gaan gebruiken.

U kunt Laravel Echo installeren met behulp van de NPM-pakketbeheerder. Natuurlijk moet je in de eerste plaats node en npm installeren als je die nog niet hebt. De rest is vrij eenvoudig, zoals te zien is in het volgende fragment.

$ npm installeert laravel-echo

Waar we in geïnteresseerd zijn, is het node_modules / laravel-echo / dist / echo.js bestand waarnaar u moet kopiëren public / echo.js.

Ja, ik begrijp het, het is een beetje overkill om gewoon een enkel JavaScript-bestand te krijgen. Als u deze oefening niet wilt doorlopen, kunt u het downloaden echo.js bestand van mijn GitHub.

En daarmee zijn we klaar met het instellen van onze klantenbibliotheken.

Back-end bestandsinstellingen

Bedenk dat we het hadden over het instellen van een applicatie waarmee gebruikers van onze applicatie berichten naar elkaar kunnen verzenden. Aan de andere kant sturen we broadcastmeldingen naar gebruikers die zijn aangemeld wanneer ze een nieuw bericht ontvangen van andere gebruikers.

In dit gedeelte maken we de bestanden die nodig zijn om de use-case te implementeren waarnaar we op zoek zijn.

Om te beginnen, laten we het maken Bericht model dat berichten bevat die door gebruikers aan elkaar zijn verzonden.

$ php artisan make: model Message --migration

We moeten ook een paar velden toevoegen zoals naar, van en bericht naar onze berichtentabel. Laten we dus het migratiebestand wijzigen voordat de migratieopdracht wordt uitgevoerd.

verhogingen ( 'id'); $ table-> integer ('from', FALSE, TRUE); $ table-> integer ('to', FALSE, TRUE); $ Tafel-> text ( 'e-mail'); $ Tafel-> timestamps (); );  / ** * Keer de migraties terug. * * @return void * / public function down () Schema :: dropIfExists ('messages'); 

Laten we nu de opdracht migreren uitvoeren waarmee de berichtentabel in de database wordt gemaakt.

$ php artisan migreren

Wanneer u een aangepaste gebeurtenis in Laravel wilt bijeenroepen, moet u een klasse voor die gebeurtenis maken. Op basis van het soort evenement reageert Laravel overeenkomstig en neemt de nodige acties.

Als de gebeurtenis een normale gebeurtenis is, roept Laravel de bijbehorende listenerklassen aan. Aan de andere kant, als de gebeurtenis een broadcast-type is, verzendt Laravel die gebeurtenis naar de websocketserver die is geconfigureerd in de config / broadcasting.php het dossier.

Omdat we in ons voorbeeld de Pusher-service gebruiken, zal Laravel evenementen naar de Pusher-server verzenden.

Laten we de volgende artisan-opdracht gebruiken om een ​​aangepaste gebeurtenisklasse te maken-NewMessageNotification.

$ php artisan make: event NewMessageNotification

Dat zou het moeten maken app / Events / NewMessageNotification.php klasse. Laten we de inhoud van dat bestand vervangen door het volgende.

bericht = $ bericht;  / ** * Download de kanalen waarop het evenement moet uitzenden. * * @return Channel | array * / public function broadcastOn () return new PrivateChannel ('user.'. $ this-> message-> to); 

Het belangrijkste om op te merken is dat de NewMessageNotification klasse implementeert de ShouldBroadcastNow interface. Dus, wanneer we een evenement organiseren, weet Laravel dat deze gebeurtenis moet worden uitgezonden.

In feite zou je ook het ShouldBroadcast interface en Laravel voegt een gebeurtenis toe aan de gebeurteniswachtrij. Het wordt verwerkt door de werknemer van de gebeurteniswachtrij wanneer dit een kans krijgt om dit te doen. In ons geval willen we het meteen uitzenden en daarom hebben we de ShouldBroadcastNow interface.

In ons geval willen we een bericht weergeven dat de gebruiker heeft ontvangen, en dus hebben we de Bericht model in het constructor-argument. Op deze manier worden de gegevens doorgegeven samen met de gebeurtenis.

Vervolgens is er de broadcastOn methode die de naam definieert van het kanaal waarop het evenement zal worden uitgezonden. In ons geval hebben we het privékanaal gebruikt omdat we de uitzending van het evenement willen beperken tot ingelogde gebruikers.

De $ This-> bericht-> om variabele verwijst naar de ID van de gebruiker waarnaar het evenement zal worden uitgezonden. Het maakt dus effectief de naam van het kanaal zoals user. USER_ID .

In het geval van privé-kanalen moet de client zich verifiëren voordat een verbinding met de websocketserver tot stand wordt gebracht. Het zorgt ervoor dat gebeurtenissen die op privé-kanalen worden uitgezonden, alleen worden verzonden naar geverifieerde clients. In ons geval betekent dit dat alleen ingelogde gebruikers zich kunnen abonneren op ons kanaal user. USER_ID .

Als je de Laravel Echo-clientbibliotheek voor kanaalabonnement gebruikt, heb je geluk! Het zorgt automatisch voor het authenticatiedeel en u hoeft alleen de kanaalroutes te definiëren.

Laten we doorgaan en een route toevoegen voor ons privékanaal in de routes / channels.php het dossier.

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

Zoals u kunt zien, hebben we de user. toUserId route voor ons privékanaal.

Het tweede argument van de kanaalmethode moet een sluitingsfunctie zijn. Laravel geeft de momenteel ingelogde gebruiker automatisch door als het eerste argument van de sluitingsfunctie en het tweede argument wordt meestal opgehaald uit de kanaalnaam.

Wanneer de client zich probeert te abonneren op het privékanaal user. USER_ID , de Laravel Echo-bibliotheek voert de benodigde authenticatie op de achtergrond uit met behulp van het XMLHttpRequest-object, of beter bekend als XHR.

Tot nu toe zijn we klaar met de installatie, dus laten we doorgaan en het testen.

Front-end bestandsinstellingen

In deze sectie maken we de bestanden die nodig zijn om onze use-case te testen.

Laten we doorgaan en een controllerbestand maken op app / Http / Controllers / MessageController.php met de volgende inhoud.

middleware (auth);  public function index () $ user_id = Auth :: user () -> id; $ data = array ('user_id' => $ user_id); retourweergave ('broadcast', $ data);  public function send () // ... // bericht wordt verzonden $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Bericht-> save (); // wil NewMessageNotification-gebeurtenisgebeurtenis uitzenden (nieuwe NewMessageNotification ($ -boodschap)); // ...

In de inhoudsopgave methode gebruiken we de uitzending bekijken, dus laten we het maken resources / views / broadcast.blade.php bekijk ook het bestand.

        Test     
Nieuwe meldingen worden realtime gewaarschuwd!

En natuurlijk moeten we ook routes toevoegen in de routes / web.php het dossier.

Route :: get ('message / index', 'MessageController @ index'); Route :: get ('message / send', 'MessageController @ send');

In de constructormethode van de controllerklasse kunt u zien dat we de auth middleware om ervoor te zorgen dat de controlemechanismemethoden alleen worden gebruikt door ingelogde gebruikers.

Vervolgens is er de inhoudsopgave methode die de uitzending uitzicht. Laten we de belangrijkste code in het weergavebestand invoeren.

    

Allereerst laden we de benodigde clientbibliotheken, Laravel Echo en Pusher, waardoor we de web-socket verbinding met de Pusher web-socket server kunnen openen.

Vervolgens maken we het exemplaar van Echo door Pusher te leveren als onze uitzendadapter en andere noodzakelijke Pusher-gerelateerde informatie.

We gaan verder en gebruiken de privémethode van Echo om zich te abonneren op het privékanaal user. USER_ID . Zoals we eerder hebben besproken, moet de client zichzelf verifiëren voordat hij zich abonneert op het privékanaal. Dus de Echo object voert de benodigde authenticatie uit door de XHR op de achtergrond te verzenden met de nodige parameters. Uiteindelijk probeert Laravel de user. USER_ID route, en deze moet overeenkomen met de route die we hebben gedefinieerd in de routes / channels.php het dossier.

Als alles goed gaat, moet u een web-socket-verbinding openen met de Pusher-websocketserver en gebeurtenissen weergeven op de user. USER_ID kanaal! Vanaf nu kunnen we alle inkomende evenementen op dit kanaal ontvangen.

In ons geval willen we luisteren naar de NewMessageNotification evenement en dus hebben we de luister methode van de Echo object om het te bereiken. Om het simpel te houden, waarschuwen we u het bericht dat we van de Pusher-server hebben ontvangen.

Dus dat was de setup voor het ontvangen van evenementen van de web-sockets-server. Vervolgens gaan we door de sturen methode in het controllerdossier die de uitzendgebeurtenis opheft.

Laten we snel de code van de sturen methode.

public function send () // ... // bericht wordt verzonden $ message = new Message; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo message from user 1 to user 2'); $ Bericht-> save (); // wil NewMessageNotification-gebeurtenisgebeurtenis uitzenden (nieuwe NewMessageNotification ($ -boodschap)); // ...

In ons geval melden we ingelogde gebruikers wanneer ze een nieuw bericht ontvangen. Dus we hebben geprobeerd om dat gedrag na te bootsen in de sturen methode.

Vervolgens hebben we de evenement helperfunctie om de NewMessageNotification evenement. Sinds de NewMessageNotification evenement is van ShouldBroadcastNow type, laadt Laravel de standaard uitzendconfiguratie van de config / broadcasting.php het dossier. Ten slotte zendt het de NewMessageNotification gebeurtenis naar de geconfigureerde websocketserver op de server user. USER_ID kanaal.

In ons geval wordt het evenement uitgezonden naar de Pusher-websocketserver op de server user. USER_ID kanaal. Als de ID van de ontvanger is 1, het evenement zal worden uitgezonden via de user.1 kanaal.

Zoals we eerder hebben besproken, hebben we al een configuratie die naar gebeurtenissen op dit kanaal luistert, zodat deze gebeurtenis moet kunnen worden ontvangen en het waarschuwingsvenster aan de gebruiker wordt weergegeven!

Laten we verder gaan en doorlopen hoe je de use-case die we tot nu toe hebben gemaakt, zou moeten testen.

Open de URL http: // uw-laravel-site-domein / bericht / index in uw browser. Als u nog niet bent ingelogd, wordt u doorgestuurd naar het inlogscherm. Zodra je bent ingelogd, zou je de uitzendweergave moeten zien die we eerder hebben gedefinieerd. Niets speciaals.

Laravel heeft al aardig wat werk op de achtergrond voor je gedaan. Omdat we de Pusher.logToConsole instelling geleverd door de Pusher client-bibliotheek, het registreert alles in de browser-console voor foutopsporingsdoeleinden. Laten we kijken wat er in de console wordt vastgelegd wanneer u de pagina http: // uw-laravel-site-domein / bericht / index opent.

Pusher: State changed: initialized -> connecting Pusher: Connecting: "transport": "ws", "url": "wss: //ws-ap2.pusher.com: 443 / app / c91c1b7e8c6ece46053b? Protocol = 7 & client = js & version = 4.1.0 & flash = false " Pusher: Bezig met verbinden: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Pusher: Status gewijzigd: verbinden -> verbonden met nieuwe socket ID 1386.68660 Pusher: Gebeurtenis verzonden: " event ":" pusher: subscribe "," data ": " auth ":" c91c1b7e8c6ece46053b: cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d "," kanaal ":" private-user.2 " Pusher: gebeurtenis-recd: " event ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" private-user.2 " Pusher: geen terugroepacties op privégebruiker.2 voor pusher: abonnementsnummer geslaagd

Het heeft de web-socket verbinding met de Pusher web-socket server geopend en zichzelf ingeschreven om naar evenementen op het privékanaal te luisteren. Natuurlijk kunt u in uw geval een andere kanaalnaam hebben op basis van de ID van de gebruiker waarmee u bent ingelogd. Laten we deze pagina open houden terwijl we verdergaan om de pagina te testen sturen methode.

Laten we vervolgens de http: // uw-laravel-site-domein / bericht / verzend-URL openen op het andere tabblad of in een andere browser. Als u een andere browser gaat gebruiken, moet u zich aanmelden om toegang te krijgen tot die pagina.

Zodra u de pagina http: // uw-laravel-site-domein / bericht / verzending opent, zou u een waarschuwingsbericht op het andere tabblad kunnen zien op http: // uw-laravel-site-domein / bericht /inhoudsopgave.

Laten we naar de console gaan om te zien wat er net is gebeurd.

Pusher: Event recd: "event": "App \\ Events \\ NewMessageNotification", "data": "message": "id": 57, "from": 1, "to": 2, "bericht ":" Demo-bericht van gebruiker 1 naar gebruiker 2 "," created_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 "," channel ":" private-gebruiker.2" Met name

Zoals u kunt zien, vertelt het u dat u zojuist het App \ Events \ NewMessageNotification gebeurtenis van de Pusher-websocketserver op de server private-gebruiker.2 Met name kanaal.

Sterker nog, je kunt ook zien wat er aan de Pusher-kant gebeurt. Ga naar je Pusher-account en navigeer naar je applicatie. Onder de debug Troosten, je zou in staat moeten zijn om berichten te zien die worden gelogd.

En dat brengt ons tot het einde van dit artikel! Hopelijk was het niet te veel in een keer omdat ik heb geprobeerd om dingen naar mijn beste weten te vereenvoudigen.

Conclusie

Vandaag hebben we een van de minst besproken functies van Laravel-uitzending doorgenomen. Hiermee kunt u real-time meldingen verzenden via webdozen. In de loop van dit artikel bouwden we een voorbeeld uit de praktijk dat het bovengenoemde concept demonstreerde.

.