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