Heute werden wir das Konzept des Rundfunks im Laravel Web Framework untersuchen. Damit können Sie Benachrichtigungen an den Client senden, wenn auf dem Server etwas passiert. In diesem Artikel verwenden wir die Pusher-Bibliothek eines Drittanbieters, um Benachrichtigungen an die Clientseite zu senden.
Wenn Sie schon einmal Benachrichtigungen vom Server an den Client senden wollten, wenn auf einem Server in Laravel etwas passiert, suchen Sie nach der Broadcasting-Funktion.
Nehmen wir beispielsweise an, Sie haben eine Messaging-Anwendung implementiert, mit der Benutzer Ihres Systems einander Nachrichten senden können. Wenn Benutzer A nun eine Nachricht an Benutzer B sendet, möchten Sie Benutzer B in Echtzeit benachrichtigen. Sie können ein Popup- oder Warnfeld anzeigen, das Benutzer B über die neue Nachricht informiert!
Es ist der perfekte Anwendungsfall, um das Konzept des Rundfunks in Laravel durchzugehen. Dies wird in diesem Artikel umgesetzt.
Wenn Sie sich fragen, wie der Server Benachrichtigungen an den Client senden kann, verwenden Sie dazu Sockets unter der Haube. Lassen Sie uns den grundlegenden Fluss von Sockets verstehen, bevor wir tiefer in die eigentliche Implementierung eintauchen.
Machen Sie sich keine Sorgen, wenn es auf einmal zu viel aussieht. Sie werden den Dreh raus bekommen, wenn wir diesen Artikel durchgehen.
Schauen wir uns als Nächstes die Standard-Konfigurationsdatei für Broadcasts an config / broadcasting.php
.
env ('BROADCAST_DRIVER', 'log'), / * | -------------------------------- -------------------------------------- Broadcast-Verbindungen | ------------------------------------------- --------------------------- | | Hier können Sie alle Broadcast-Verbindungen definieren, die verwendet werden sollen um Ereignisse an andere Systeme oder über Websockets zu senden. Proben von | Jeder verfügbare Verbindungstyp wird in diesem Array bereitgestellt. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'secret' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'),], 'redis' => ['driver' => 'redis', 'verbindung' => 'default',], 'log' => ['driver' => 'log ',],' null '=> [' driver '=>' null ',],],];
Standardmäßig unterstützt Laravel mehrere Broadcast-Adapter im Core selbst.
In diesem Artikel verwenden wir die Pusher
Broadcast-Adapter. Zu Debugging-Zwecken können Sie auch den Protokolladapter verwenden. Natürlich, wenn Sie das verwenden Log
Wenn der Adapter nicht empfangen wird, erhält der Client keine Ereignisbenachrichtigungen, und er wird nur beim protokolliert laravel.log
Datei.
Ab dem nächsten Abschnitt werden wir uns sofort mit der tatsächlichen Implementierung des oben genannten Anwendungsfalls beschäftigen.
Im Rundfunk gibt es verschiedene Arten von Kanälen - öffentlich, privat und Präsenz. Wenn Sie Ihre Ereignisse öffentlich übertragen möchten, ist dies der öffentliche Kanal, den Sie verwenden sollten. Umgekehrt wird der private Kanal verwendet, wenn Sie Ereignisbenachrichtigungen auf bestimmte private Kanäle beschränken möchten.
In unserem Anwendungsfall möchten wir Benutzer benachrichtigen, wenn sie eine neue Nachricht erhalten. Um Broadcast-Benachrichtigungen zu erhalten, muss der Benutzer angemeldet sein. In unserem Fall müssen wir daher den privaten Kanal verwenden.
Erstens müssen Sie das Standard-Laravel-Authentifizierungssystem aktivieren, damit Funktionen wie Registrierung, Anmeldung und ähnliches sofort funktionieren. Wenn Sie sich nicht sicher sind, wie Sie das tun sollen, bietet die offizielle Dokumentation einen schnellen Einblick.
Da werden wir die verwenden Pusher
Drittanbieter-Service Als Web-Socket-Server müssen Sie ein Konto erstellen und sicherstellen, dass Sie die erforderlichen API-Anmeldeinformationen für Ihre Post-Registrierung haben. Wenn Sie Probleme beim Erstellen haben, zögern Sie nicht, mich im Kommentarbereich zu fragen.
Als Nächstes müssen wir das Pusher PHP SDK installieren, damit unsere Laravel-Anwendung Broadcast-Benachrichtigungen an den Pusher-Websocket-Server senden kann.
Führen Sie in Ihrem Laravel-Anwendungsstamm den folgenden Befehl aus, um ihn als Composer-Paket zu installieren.
$ composer erfordert den Pusher / Pusher-PHP-Server "~ 3.0"
Nun ändern wir die Broadcast-Konfigurationsdatei, um den Pusher-Adapter als unseren Standard-Broadcast-Treiber zu aktivieren.
env ('BROADCAST_DRIVER', 'pusher'), / * | -------------------------------- -------------------------------------- Broadcast-Verbindungen | ------------------------------------------- --------------------------- | | Hier können Sie alle Broadcast-Verbindungen definieren, die verwendet werden sollen um Ereignisse an andere Systeme oder über Websockets zu senden. Proben von | Jeder verfügbare Verbindungstyp wird in diesem Array bereitgestellt. | * / 'connections' => ['pusher' => ['driver' => 'pusher', 'key' => env ('PUSHER_APP_KEY'), 'secret' => env ('PUSHER_APP_SECRET'), 'app_id' => env ('PUSHER_APP_ID'), 'options' => ['cluster' => 'ap2', 'encrypted' => true],], 'redis' => ['driver' => 'redis', ' Verbindung '=>' default ',],' log '=> [' driver '=>' log ',],' null '=> [' driver '=>' null ',],],];
Wie Sie sehen, haben wir den Standard-Broadcast-Treiber in Pusher geändert. Wir haben auch Cluster- und verschlüsselte Konfigurationsoptionen hinzugefügt, die Sie eigentlich vom Pusher-Konto erhalten haben sollten.
Außerdem werden Werte aus Umgebungsvariablen abgerufen. Stellen wir also sicher, dass wir die folgenden Variablen in der .env
Datei richtig.
BROADCAST_DRIVER = Schieber PUSHER_APP_ID = YOUR_APP_ID PUSHER_APP_KEY = YOUR_APP_KEY PUSHER_APP_SECRET = YOUR_APP_SECRET
Als nächstes musste ich einige Kern-Laravel-Dateien ändern, um sie mit dem neuesten Pusher SDK kompatibel zu machen. Natürlich empfehle ich keine Änderungen am Core-Framework, aber ich möchte nur hervorheben, was zu tun ist.
Mach weiter und öffne die Verkäufer / Laravel / Rahmen / src / Illuminate / Rundfunk / Rundfunk / Rundfunk / PusherBroadcaster.php
Datei. Ersetzen Sie einfach das Snippet Verwenden Sie Pusher;
mit verwenden Sie Pusher \ Pusher;
.
Als nächstes öffnen wir die Verkäufer / Laravel / Framework / src / Illuminate / Broadcasting / BroadcastManager.php
Datei und nehmen Sie eine ähnliche Änderung im folgenden Snippet vor.
neuen PusherBroadcaster zurückgeben (neuer \ Pusher \ Pusher ($ config ['key'] "), $ config ['secret'], $ config ['app_id'], Arr :: get ($ config, 'options', [])) );
Schließlich aktivieren wir den Broadcast-Dienst in config / app.php
indem Sie den Kommentar in der folgenden Zeile entfernen.
App \ Providers \ BroadcastServiceProvider :: Klasse,
Bisher haben wir serverspezifische Bibliotheken installiert. Im nächsten Abschnitt werden Client-Bibliotheken beschrieben, die ebenfalls installiert werden müssen.
Beim Rundfunk ist es die Aufgabe des Clients, Kanäle zu abonnieren und auf gewünschte Ereignisse zu achten. Unter der Haube wird dies durch Öffnen einer neuen Verbindung zum Websocket-Server erreicht.
Glücklicherweise müssen wir kein komplexes JavaScript-Material implementieren, um dieses Ziel zu erreichen, da Laravel bereits eine nützliche Client-Bibliothek, Laravel Echo, enthält, die uns beim Umgang mit Sockets auf der Clientseite hilft. Außerdem unterstützt es den Pusher-Dienst, den wir in diesem Artikel verwenden werden.
Sie können Laravel Echo mit dem NPM-Paketmanager installieren. Natürlich müssen Sie node und npm an erster Stelle installieren, wenn Sie sie noch nicht haben. Der Rest ist ziemlich einfach, wie im folgenden Ausschnitt gezeigt.
$ npm installiere Laravel-Echo
Was uns interessiert, ist das node_modules / laravel-echo / dist / echo.js
Datei, in die Sie kopieren sollten public / echo.js
.
Ja, ich verstehe, es ist ein bisschen übertrieben, nur eine einzige JavaScript-Datei zu erhalten. Wenn Sie diese Übung nicht durchführen möchten, können Sie das herunterladen echo.js
Datei von meinem GitHub.
Damit sind wir mit der Einrichtung unserer Client-Bibliotheken fertig.
Denken Sie daran, dass wir über das Einrichten einer Anwendung gesprochen haben, mit der Benutzer unserer Anwendung einander Nachrichten senden können. Auf der anderen Seite senden wir Broadcast-Benachrichtigungen an Benutzer, die angemeldet sind, wenn sie eine neue Nachricht von anderen Benutzern erhalten.
In diesem Abschnitt erstellen wir die Dateien, die erforderlich sind, um den von uns gesuchten Anwendungsfall zu implementieren.
Beginnen wir mit dem Botschaft
Modell, das Nachrichten enthält, die von Benutzern aneinander gesendet werden.
$ php Handwerker make: model Message --migration
Wir müssen auch ein paar Felder wie hinzufügen zu
, von
und Botschaft
zu unserer Nachrichtentabelle. Ändern wir also die Migrationsdatei, bevor Sie den Migrationsbefehl ausführen.
Inkremente ('id'); $ table-> integer ('from', FALSE, TRUE); $ table-> integer ('to', FALSE, TRUE); $ table-> text ('message'); $ table-> timestamps (); ); / ** * Kehren Sie die Migrationen um. * * @return void * / public function down () Schema :: dropIfExists ('messages');
Führen wir nun den Migrationsbefehl aus, der die Nachrichtentabelle in der Datenbank erstellt.
$ php Handwerker migrieren
Wann immer Sie ein benutzerdefiniertes Ereignis in Laravel auslösen möchten, sollten Sie eine Klasse für dieses Ereignis erstellen. Je nach Art des Ereignisses reagiert Laravel entsprechend und ergreift die notwendigen Maßnahmen.
Wenn das Ereignis ein normales Ereignis ist, ruft Laravel die zugehörigen Listener-Klassen auf. Wenn das Ereignis jedoch vom Broadcast-Typ ist, sendet Laravel dieses Ereignis an den Websocket-Server, der im konfiguriert ist config / broadcasting.php
Datei.
Da wir in unserem Beispiel den Pusher-Dienst verwenden, sendet Laravel Ereignisse an den Pusher-Server.
Verwenden Sie den folgenden Befehl, um eine benutzerdefinierte Ereignisklasse zu erstellen-NewMessageNotification
.
$ php Handwerker make: event NewMessageNotification
Das sollte das schaffen app / Events / NewMessageNotification.php
Klasse. Lassen Sie uns den Inhalt dieser Datei durch Folgendes ersetzen.
message = $ message; / ** * Liefert die Kanäle, auf denen das Ereignis gesendet werden soll. * * @return Channel | array * / public function broadcastOn () return new PrivateChannel ('user.'. $ this-> message-> to);
Wichtig ist, dass das NewMessageNotification
Klasse implementiert die ShouldBroadcastNow
Schnittstelle. Wenn wir also ein Ereignis erheben, weiß Laravel, dass dieses Ereignis gesendet werden sollte.
Tatsächlich könnten Sie auch die implementieren SollteBroadcast
und Laravel fügt ein Ereignis in die Ereigniswarteschlange ein. Sie wird vom Worker der Ereigniswarteschlange verarbeitet, wenn er die Möglichkeit dazu hat. In unserem Fall wollen wir es sofort ausstrahlen, und deshalb haben wir das verwendet ShouldBroadcastNow
Schnittstelle.
In unserem Fall möchten wir eine Nachricht anzeigen, die der Benutzer erhalten hat Botschaft
Modell im Konstruktorargument. Auf diese Weise werden die Daten mit dem Ereignis weitergegeben.
Als nächstes gibt es die broadcastOn
Methode, die den Namen des Kanals definiert, auf dem das Ereignis übertragen wird. In unserem Fall haben wir den privaten Kanal verwendet, um die Ereignisübertragung auf angemeldete Benutzer zu beschränken.
Das $ this-> message-> to
Variable bezieht sich auf die ID des Benutzers, an den das Ereignis gesendet wird. Somit macht es den Kanalnamen effektiv Benutzer. USER_ID
.
Bei privaten Kanälen muss sich der Client authentifizieren, bevor eine Verbindung zum Websocket-Server hergestellt werden kann. Dadurch wird sichergestellt, dass Ereignisse, die auf privaten Kanälen gesendet werden, nur an authentifizierte Clients gesendet werden. In unserem Fall bedeutet dies, dass nur angemeldete Benutzer unseren Kanal abonnieren können Benutzer. USER_ID
.
Wenn Sie die Laravel Echo-Client-Bibliothek für das Abonnement von Kanälen verwenden, haben Sie Glück! Es kümmert sich automatisch um den Authentifizierungsteil, und Sie müssen nur die Kanalrouten definieren.
Lassen Sie uns fortfahren und eine Route für unseren privaten Kanal in der routen / kanäle.php
Datei.
id === (int) $ id; ); Broadcast :: channel ('user. ToUserId', Funktion ($ user, $ toUserId) return $ user-> id == $ toUserId;);
Wie Sie sehen können, haben wir die definiert user. toUserId
Route für unseren privaten Kanal.
Das zweite Argument der channel-Methode sollte eine Abschlussfunktion sein. Laravel übergibt den aktuell angemeldeten Benutzer automatisch als erstes Argument der Schließungsfunktion, und das zweite Argument wird normalerweise vom Kanalnamen abgerufen.
Wenn der Client versucht, den privaten Kanal zu abonnieren Benutzer. USER_ID
, Die Laravel-Echo-Bibliothek führt die erforderliche Authentifizierung im Hintergrund mithilfe des XMLHttpRequest-Objekts aus (XHR).
Bis jetzt sind wir mit dem Setup fertig, also testen wir es.
In diesem Abschnitt erstellen wir die Dateien, die zum Testen unseres Anwendungsfalls erforderlich sind.
Machen wir weiter und erstellen eine Controller-Datei unter app / Http / Controller / MessageController.php
mit folgenden Inhalten.
Middleware ('auth'); public function index () $ user_id = Auth :: user () -> id; $ data = array ('user_id' => $ user_id); Rückansicht ('Broadcast', $ data); public function send () //… // Nachricht wird gesendet $ message = new Nachricht; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo-Nachricht von Benutzer 1 an Benutzer 2'); $ message-> save (); // möchte NewMessageNotification-Ereignis übertragen (new NewMessageNotification ($ message)); //…
In dem Index
Methode verwenden wir die Übertragung
Ansicht, also erstellen wir die resources / views / broadcast.blade.php
Datei ansehen.
Prüfung Eine neue Benachrichtigung wird in Echtzeit angezeigt!
Natürlich müssen wir auch Routen in der routen / web.php
Datei.
Route :: get ('message / index', 'MessageController @ index'); Route :: get ('message / send', 'MessageController @ send');
In der Konstruktormethode der Controller-Klasse können Sie sehen, dass wir das verwendet haben Auth
Middleware, um sicherzustellen, dass auf Controllermethoden nur von angemeldeten Benutzern zugegriffen wird.
Als nächstes gibt es die Index
Methode, die das macht Übertragung
Aussicht. Lassen Sie uns den wichtigsten Code in die Ansichtsdatei ziehen.
Zunächst laden wir die erforderlichen Client-Bibliotheken, Laravel Echo und Pusher, sodass wir die Web-Socket-Verbindung zum Pusher-Web-Socket-Server öffnen können.
Als Nächstes erstellen wir die Instanz von Echo, indem wir Pusher als unseren Broadcast-Adapter und andere erforderliche Informationen zum Pusher bereitstellen.
Um weiterzukommen, verwenden wir die private Methode von Echo, um den privaten Kanal zu abonnieren Benutzer. USER_ID
. Wie bereits erwähnt, muss sich der Client authentifizieren, bevor er den privaten Kanal abonniert. Und so kam es dass der Echo
object führt die erforderliche Authentifizierung durch, indem das XHR mit den erforderlichen Parametern im Hintergrund gesendet wird. Schließlich versucht Laravel, das zu finden Benutzer. USER_ID
Route, und es sollte der Route entsprechen, die wir in definiert haben routen / kanäle.php
Datei.
Wenn alles gut geht, sollten Sie eine Websockel-Verbindung mit dem Pusher-Websocket-Server haben, und es werden Ereignisse auf der Website aufgelistet Benutzer. USER_ID
Kanal! Ab sofort können wir alle eingehenden Ereignisse auf diesem Kanal empfangen.
In unserem Fall wollen wir auf das hören NewMessageNotification
Ereignis und damit haben wir die verwendet Hör mal zu
Methode der Echo
Ziel, es zu erreichen. Der Einfachheit halber alarmieren wir einfach die Nachricht, die wir vom Pusher-Server erhalten haben.
Das war also das Setup für den Empfang von Ereignissen vom Websocket-Server. Als nächstes gehen wir durch senden
Methode in der Controller-Datei, die das Broadcast-Ereignis auslöst.
Lassen Sie uns schnell den Code der senden
Methode.
öffentliche Funktion send () //… // Nachricht wird gesendet $ message = new Nachricht; $ message-> setAttribute ('from', 1); $ message-> setAttribute ('to', 2); $ message-> setAttribute ('message', 'Demo-Nachricht von Benutzer 1 an Benutzer 2'); $ message-> save (); // möchte NewMessageNotification-Ereignis übertragen (new NewMessageNotification ($ message)); //…
In unserem Fall benachrichtigen wir angemeldete Benutzer, wenn sie eine neue Nachricht erhalten. Wir haben also versucht, dieses Verhalten im Internet nachzuahmen senden
Methode.
Als nächstes haben wir die verwendet Veranstaltung
Helferfunktion zum Anheben der NewMessageNotification
Veranstaltung. Seit der NewMessageNotification
Ereignis ist von ShouldBroadcastNow
Typ, lädt Laravel die Standard-Broadcast-Konfiguration aus der config / broadcasting.php
Datei. Schließlich sendet es die NewMessageNotification
Ereignis an den konfigurierten Websocket-Server auf der Benutzer. USER_ID
Kanal.
In unserem Fall wird das Ereignis an den Pusher-Websocket-Server auf der Website gesendet Benutzer. USER_ID
Kanal. Wenn die ID des Empfängerbenutzers lautet 1
, Die Veranstaltung wird über das Internet übertragen Benutzer.1
Kanal.
Wie bereits erwähnt, verfügen wir bereits über ein Setup, das Ereignisse auf diesem Kanal überwacht. Es sollte daher möglich sein, dieses Ereignis zu empfangen, und dem Benutzer wird das Benachrichtigungsfeld angezeigt!
Gehen wir weiter und gehen wir durch, wie Sie den von uns erstellten Anwendungsfall testen sollen.
Öffnen Sie die URL http: // Ihre-Laravel-Site-Domain / Nachricht / Index in Ihrem Browser. Wenn Sie noch nicht angemeldet sind, werden Sie zum Anmeldebildschirm weitergeleitet. Sobald Sie angemeldet sind, sollten Sie die Broadcast-Ansicht sehen, die wir zuvor definiert haben - nichts Besonderes.
In der Tat hat Laravel bereits für Sie im Hintergrund viel getan. Da haben wir die aktiviert Pusher.logToConsole
Diese Einstellung wird von der Pusher-Client-Bibliothek bereitgestellt und protokolliert alles in der Browserkonsole zu Debugging-Zwecken. Lassen Sie uns sehen, was an der Konsole protokolliert wird, wenn Sie auf die Seite http: // Ihre-Laravel-Site-Domain / Nachricht / Index zugreifen.
Pusher: Status geändert: initialisiert -> 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: Connecting: " transport ":" xhr_streaming "," url ":" https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client= js & version = 4.1.0 " Druckertreiber in der neuen Sockel-ID: 1386.68660 Druckerstück: Ereignis gesendet: " Ereignis ":" Druckstempel: Abonnieren "," Daten ":" "auth": " "," channel ":" private-user.2 " Pusher: Event recd: " event ":" pusher_internal: subscription_succeeded "," data ": ," channel ":" private-user.2 " Pusher: Keine Rückrufe für Privatbenutzer.2 für Pusher: Subscribe_succeeded
Es hat die Web-Socket-Verbindung mit dem Pusher-Web-Socket-Server geöffnet und sich selbst abonniert, um Ereignisse auf dem privaten Kanal zu überwachen. Natürlich können Sie in Ihrem Fall einen anderen Kanalnamen haben, basierend auf der ID des Benutzers, mit dem Sie angemeldet sind. Lassen Sie uns jetzt diese Seite geöffnet, während wir uns zum Testen von senden
Methode.
Als nächstes öffnen wir die http: // Ihre-Laravel-Site-Domain / Nachricht / Sende-URL in der anderen Registerkarte oder in einem anderen Browser. Wenn Sie einen anderen Browser verwenden, müssen Sie sich anmelden, um auf diese Seite zugreifen zu können.
Sobald Sie die Seite http: // your-laravel-site-domain / message / send öffnen, sollte auf der anderen Registerkarte unter http: // your-laravel-site-domain / message eine Warnmeldung angezeigt werden /Index.
Navigieren wir zur Konsole, um zu sehen, was gerade passiert ist.
Pusher: Event recd: "event": "App \\ Events \\ NewMessageNotification", "data": "message": "id": 57, "from": 1, "bis": 2, "message ":" Demo-Nachricht von Benutzer 1 an Benutzer 2 "," created_at ":" 2018-01-13 07:10:10 "," updated_at ":" 2018-01-13 07:10:10 "," channel ":" private-user.2 "
Wie Sie sehen, sagt es Ihnen, dass Sie gerade die erhalten haben App \ Events \ NewMessageNotification
Ereignis vom Pusher-Websocket-Server auf der Privatnutzer.2
Kanal.
Tatsächlich können Sie auch am Pusher-Ende sehen, was dort draußen passiert. Gehen Sie zu Ihrem Pusher-Konto und navigieren Sie zu Ihrer Anwendung. Unter dem Debuggen Konsole, Sie sollten in der Lage sein, Nachrichten anzuzeigen, die protokolliert werden.
Und das bringt uns zum Ende dieses Artikels! Hoffentlich war es nicht zu viel, da ich versucht habe, die Dinge nach meinem besten Wissen zu vereinfachen.
Heute haben wir uns mit einer der am wenigsten diskutierten Funktionen des Laravel-Rundfunks befasst. Sie können mit Web-Sockets Echtzeit-Benachrichtigungen senden. Im Verlauf dieses Artikels haben wir ein reales Beispiel erstellt, das das oben genannte Konzept demonstrierte.
.