Laravel Websockets 443 ├╝ber https - 443

 

Mit Hilfe von WebSockets k├Ânnen Echtzeit-Webanwendungen umgesetzt werden. WebSockets erm├Âglichen dem Browser auf bestimmte Anforderungen vom Server zu warten, der Browser muss also nicht regelm├Ą├čig nach Updates vom Server fragen, er wird vom Server aktiv informiert.┬á

Eine WebSockets-L├Âsung kann in Laravel mit Pusher oder socket.io implementiert werden. Hier ein einfaches Beispiel, die spezifischen Einstellungen f├╝r Pusher und ECHO mit socket.io folgen im Anschluss.

Beispiel

Der Browser erstellt mittels Javascript eine WebSocket-Verbindung zu Pusher oder einem eigenen socket.io Server.

Ich verwende dazu die URL: /eventtest

An dieser Stelle wartet der Browser auf Events vom Server.

Beim Aufruf der URL /eventfire wird ein Event ausgel├Âst:

Die URL /eventtest wird ├╝ber das Ausl├Âsen des Events informiert und regiert darauf mit einem Alert:

/routes/web.php

F├╝r den Aufruf der beiden Seiten erstellen wir 2 Routes

use App\Events\EventTrigger;

Route::view('/eventtest', 'eventListener');
route::get('/eventfire', function () {
event(new EventTrigger());
});

/eventtest l├Ądt eine View

/eventfire l├Ądt direkt einen Event, welchen wir wie folgt erstellen k├Ânnen:

Trigger

php artisan make:event EventTrigger

 /app/Events/EventTrigger.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class EventTrigger implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('channel-test');
    }
}

In der Datei /config/app.php muss zudem die Zeile:┬áApp\Providers\BroadcastServiceProvider::class, aktiviert werden, diese ist standardm├Ą├čig auskommentiert

ShouldBroadcast vs. ShouldBroadcastNow

ShouldBroadcast verwendet den Standard-Queue-Driver, ShouldBroadcastNow verwendet "sync" als Queue-Driver, Events werden also sofort rausgeschickt.

Sollte der Standard-Queue-Driver sync sein, macht es also keinen Unterschied ob ShouldBroadcastNow oder ShouldBroadcast verwendet wird.

Redis als Queue-Driver:

Sollte als Queue-Driver Redis zum Einsatz kommen, in der .env -Datei wird also

QUEUE_DRIVER=redis 

verwendet,┬áwird f├╝r das Abhandeln der Events noch ein laufender┬áQueue-Worker ben├Âtigt:

Konsole: php artisan queue:work redis

Wie vorhin beschrieben muss dazu ShouldBroadcast und nicht ShouldBroadcastNow in EventTrigger.php verwendet werden.

Voraussetzung ist die Installation des Redis-Servers, siehe: www.libe.net/ubuntu-redis zudem muss Redis in der .env-Datei konfiguriert werden:

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=???
REDIS_PORT=6379
permantentes Ausf├╝hren des Queue Workers:

Ubuntu/Debian sudo apt-get install supervisor

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/vhosts/domain/laravelfolder/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/vhosts/domain/laravelfolder/laravel/storage/logs/worker.log
sudo supervisorctl stop all 
sudo supervisorctl reread
sudo supervisorctl reload

Der Status kann mit

supervisorctl status

├╝berpr├╝ft werden ...

/resources/views/eventListener.blade.php

<!DOCTYPE html>
<html>
  <head>
      <title>EventTest</title>
	    <link rel="stylesheet" href="/css/app.css">
	  	<meta name="csrf-token" content="{{ csrf_token() }}">
  </head>
  <body>
	<div id="app2">
		<p>test</p>
	</div>
 	<script src="/js/app.js" charset="utf-8"></script>   
 	<script>
 	new Vue({
 		el: '#app2',

 		created() {
 			Echo.channel('channel-test').listen('EventTrigger', (e) => {
 			 alert('EventTriggered');
 			};
 		}
 	});</script>
  </body>
</html>

Private

/app/Events/EventTrigger.php: PrivateChannel

<?php

namespace App\Events;
use Illuminate\Support\Facades\Auth;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;


class EventTrigger implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct()
    {
        
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    { 
        return new PrivateChannel('App.User.'.  Auth::user()->id );
    }
}

routes/channels.php - Client can not be authenticated, got HTTP status 403

Damit die Authentifizierung f├╝r private Channels ├╝berpr├╝ft wird, m├╝ssen die User in channels.php ├╝berpr├╝ft werden.

Broadcast::channel('App.User.{id}', function ($user, $id) {
    return (int) $user->id === (int) $id;
});

Sollte die ├ťberpr├╝fung fehlschlagen, taucht im Log des Echo-Servers folgender Fehler auf:┬áClient can not be authenticated, got HTTP status 403

/resources/views/eventListener.blade.php

<!DOCTYPE html>
<html>
  <head>
      <title>EventTest</title>
	    <link rel="stylesheet" href="/css/app.css">
	  	<meta name="csrf-token" content="{{ csrf_token() }}">
  </head>
  <body> 
	<div id="app2">
		<p>test</p>
	</div>
 	<script src="/js/app.js" charset="utf-8"></script>   
	  <script>
		  const app2 = new Vue({
	el: '#app2',
	created() {
		Echo.private('App.User.{{ Auth::user()->id }}')
		.listen('EventTrigger', (e) => {
		 alert('EventTriggered');
		});
		}
	});
	 </script>
  </body>
</html>
positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE f├╝r deine Bewertung!

Fragen / Kommentare