Laravel Websockets

Laravel Websockets

Laravel Websockets: Egy átfogó útmutató valós idejű webalkalmazásokhoz

A mai világban egyre fontosabbá válik a valós idejű kommunikáció a webalkalmazásokban. A felhasználók elvárják, hogy az frissítések és értesítések azonnal megjelenjenek, anélkül, hogy frissíteniük kellene az oldalt. Ez, amikor a Laravel Websockets bejön a képbe. A Laravel Websockets egy olyan csomag, amely lehetővé teszi a fejlesztők számára, hogy könnyen valós idejű alkalmazásokat hozzanak létre a Laravel segítségével.

Ebben a bejegyzésben feltárjuk, hogy mi a Laravel Websockets, hogyan működik és néhány kulcsfontosságú jellemzője.

Hogyan találjuk meg a megfelelő websocket hátteret a Laravel számára

Ha megfelelő WebSocket háttérrendszert szeretne találni a Laravel számára, először áttekintést kell kapnia arról, hogy mely megoldások felelnek meg a célnak.
Mivel több megoldás is elérhető, először a leggyakrabban használtakat értékeltük, mielőtt valamelyiket választanánk. Tekintse meg az alábbi listát, hogy megtalálja az egyes lehetséges megvalósítások előnyeit és hátrányait.

NévTechnológiaLicenszAktualitásSkálázhatóságProtokoll
Laravel Echo ServerNodeJSMITmediumhighsocket.io
Laravel WebsocketsPHPMIThighok, v2-betapusher
SoketiC, NodeJSMITmediumtoppusher
Pusher.comSaascommercialhightoppusher
AblySaascommercialhightoppusher

Laravel Echo szerver

A Laravel Echo Server a NodeJS-en és a népszerű websocket.io könyvtáron alapul. Ez volt az első ajánlott Websocket szerver implementáció a Laravel számára. A "laravel-echo-server" a NodeJS-től elvárható módon nagyon gyorsan és stabilan fut. A projektet azonban jelenleg csak egy maroknyi önkéntes tartja karban, aminek következtében az idő múlásával felhalmozódik néhány probléma.

Például a Laravel Echo Server legutóbbi verziója (1.6.2, a cikk írásakor), amely 2020 májusában jelent meg, nem működik a legújabb Socket.io klienskönyvtárakkal, és nem tartalmaz biztonsági és stabilitási javításokat. Egy kis plusz pont: a skálázhatóság a Redis segítségével általában támogatott. A Laravel Echo Server jövőbeli fejlesztése azonban bizonytalannak tűnik.

Soketi

A nyílt forráskódú Websocket háttérrendszer soketi még viszonylag új a piacon. A gyors μWebSockets háttérrendszerre épül, amely az eredeti C könyvtár NodeJS portja. A Soketi a Pusher-Protocolt valósítja meg, amelyet a Laravel teljesen támogat. A Websocket szerver modern felépítése mellett Docker konténerben is optimálisan üzemeltethető és skálázható. A soketi szerver figyelése Prometheusszal és számos adatbázis-háttérrel szintén támogatott.

Mi az a Laravel Websockets csomag?

A Githubon több mint 4.000 csillaggal rendelkező Laravel Websockets jelenleg a legnépszerűbb Websocket megoldás a Laravel számára – és ez teljesen jogos. Ideális azoknak a fejlesztőknek, akik először dolgoznak a WebSockets szolgáltatással, vagy azoknak, akik gyorsan szeretnék üzembe helyezni. A Laravel Wessockets az egyetlen elérhető megoldás, amely natívan PHP-n fut, és ezért közvetlenül a Laravel alkalmazás mellett ülhet.

A Laravel Websockets egy olyan csomag, amely egyszerű és hatékony megoldást nyújt a valós idejű alkalmazások létrehozásához a Laravel segítségével. Lehetővé teszi a fejlesztők számára, hogy könnyedén beállítsanak egy Websocket szervert, és használják azt valós idejű kommunikáció kezelésére a kliensek és a szerverek között.A rendkívül stabil és erőforrás-takarékos szerver, a népszerű PHP React könyvtáron alapul, továbbá egy praktikus hibakereső irányítópultot is tartalmaz. Az irányítópult lehetővé teszi bármely esemény gyors tesztelését és hibakeresését.

Mi lehet a gond ? A Laravel Websockets jelenleg stabil, `1.x` és `2.x` béta verzióban érhető el. A "2.x" verzió egy teljes újraírás, amely lehetőséget kínál a Websocket szerver skálázhatóságára. Annál inkább sajnálatos, hogy a `2.x` verzió eddig csak béta verzióban volt elérhető.

Hogyan működik?

A Laravel Websockets a kliens és a szerver között egy tartós kapcsolatot hoz létre. Ez a kapcsolat a Websocket protokoll segítségével jön létre, amely lehetővé teszi a kliens és a szerver közötti kétirányú kommunikációt.

Miután a kapcsolatot létrehozták, a szerver üzeneteket küldhet a kliensnek, és fordítva is. Ezeket az üzeneteket valós idejű frissítésre, értesítések küldésére és sok más dologra is lehet használni.

A Laravel Websockets Redis-t használ pub/sub üzenetközvetítőként, hogy lehetővé tegye a több szerver közötti kommunikációt. Ez azt jelenti, hogy ha több szerver futtatja az alkalmazását, azok minden Redis-t használva kommunikálhatnak egymással.

A Laravel WebSockets főbb jellemzői

Egyszerű beállítás: A Laravel WebSockets használata rendkívül egyszerű és gyors. A csomagot telepíthetjük Composer segítségével, majd a konfigurációs fájlban megadhatjuk a beállításokat.

Redis integráció: A Laravel WebSockets Redis-t használ pub/sub üzenetközvetítőként, hogy lehetővé tegye a több szerver közötti kommunikációt. Ez azt jelenti, hogy ha több szerver futtatja az alkalmazását, azok minden Redis-t használva kommunikálhatnak egymással.

Beépített jelenlétkezelés: A Laravel WebSockets-ben beépített jelenlétkezelő rendszer található, amely lehetővé teszi a felhasználók jelenlétét és az aktív csatornákat követni. Ez különösen hasznos lehet olyan alkalmazásokban, amelyek valós idejű csevegést és közösségi funkciókat tartalmaznak.

Csatornakezelés: A Laravel WebSockets lehetővé teszi a különböző csatornák létrehozását a kliensek és a szerverek közötti kommunikációhoz. A csatornák a Redis pub/sub rendszerén alapulnak, és lehetővé teszik a valós idejű adatok küldését és fogadását.

Telepítés néhány lépésben

A Laravel WebSockets és a Pusher SDK az 5.0-s verzióban egyszerűen telepíthető a megfelelő Laravel projektbe a következő parancsokkal:

composer require beyondcode/laravel-websockets "^2.0"
composer require pusher/pusher-php-server "^5.0"

A Laravel Websockets 2.0-s verziójának telepítése előtt állunk, mert a Redis-t szeretnénk használni háttérként és a Websocket szerver vízszintes méretezhetőségére.

Most fel kell készítenünk a DB migrációkat a megfelelő működésre a következő paranccsal:

php artisan vendor:publish --provider ="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"

 

php artisan migrate

 

A háttérben a Laravel adatbázisban készülnek el a Websocket szerver hibakeresési irányítópultjához szükséges táblák. Most a `config/websockets.php` fájlban lévő Websocket szerver konfigurálása:

// config/websockets.php
​
return [
    // ...
​
    'apps' => [
        [
            'id' => env('PUSHER_ID', 'test'),
            'name' => env('APP_NAME', 'test'),
            'host' => env('PUSHER_HOST', 'test.test'),
            'key' => env('PUSHER_KEY', 'test'),
            'secret' => env('PUSHER_SECRET'),
            'path' => env('PUSHER_PATH'),
            'capacity' => null,
            'enable_client_messages' => false,
            'enable_statistics' => true,
            'allowed_origins' => [
                env('LARAVEL_WEBSOCKETS_DOMAIN'),
            ],
        ],
    ],
​
    'replication' => [
        'mode' => env('WEBSOCKETS_REPLICATION_MODE', 'redis'),
        'modes' => [
            // ...
​
            'redis' => [
                'connection' => env('WEBSOCKETS_REDIS_REPLICATION_CONNECTION', 'websocket'),
                'channel_manager' => App\Service\WebSockets\RedisChannelManager::class,
​
            // ...
        ],
​
    // ...
];

 

A WebSocket szerver sikeres konfigurációjához a PUSHER_ID, PUSHER_HOST, PUSHER_KEY és PUSHER_SECRET környezeti változókat megfelelően kell használni. Ha azt tervezi, hogy a WebSocket Servert egy külön szerveren futtatja, a LARAVEL_WEBSOCKETS_DOMAIN környezeti változó elengedhetetlen a CORS (Cross-Origin-Resource-Sharing) problémák elkerülése érdekében.

Példa változók az .env-ben:

BROADCAST_DRIVER=pusher
WEBSOCKETS_REPLICATION_MODE=redis
PUSHER_ID=app
PUSHER_HOST=app.test
PUSHER_SCHEME=http
PUSHER_KEY=app
PUSHER_SECRET=80f5dd30-c24e-4088-87ae-d57d0059f109

 

php artisan websockets:serve

 

Event-Broadcasting beállítása

A WebSocket szerver üzembe helyezése után felvetődik a kérdés, hogy a Laravel alkalmazás a szerveroldali Laravel alkalmazásból adatokat – úgynevezett broadcast eseményeket – küldjön a kliensnek a WebSocketen keresztül.

Azonban, mint korábban említettük, ez a beállítás gyerekjáték, mivel a Laravel Framework beépített támogatással érkezik a push szerverrel történő kommunikációhoz.

Ezután a korábban telepített Laravel Websockets szervert a `config/broadcasting.php` fájlban konfiguráljuk.

// config/broadcasting.php
​
return [
    // ...
​
    'default' => env('BROADCAST_DRIVER', 'pusher'),
​
    'connections' => [
        'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_KEY'),
            'secret' => env('PUSHER_SECRET'),
            'app_id' => env('PUSHER_ID'),
            'options' => [
                'host' => env('PUSHER_PUSH_HOST', 'api'),
                'port' => env('PUSHER_PUSH_PORT', 6001),
                'scheme' => env('PUSHER_PUSH_SCHEME', 'http'),
                'encrypted' => true,
            ],
        ],
​
        // ...
    ],
​
    // ...
];

 

Győződjön meg arról, hogy a konfigurált pusher megegyezik a "config/websocket.php" fájlban beállított értékkel, mivel az alkalmazásnak ugyanazzal a névvel kell kommunikálnia a pusher szerverrel. Például egy Docker-alapú beállításnál itt választanánk ki a Docker-tároló nevét.

Egyébként, ahogy az a Laravelnél lenni szokott, minden változót az .env fájlban kell definiálni, nem pedig a konfigurációs fájlba írni. Az env parancs ábrázolt második paraméterei csak akkor alapértelmezett értékek, ha a megfelelő környezeti változó nincs megadva.

Az alkalmazásazonosítónak meg kell egyeznie a pusher kliensben később használt alkalmazásazonosítóval.

Aktiválnunk kell a broadcast szolgáltatót a Laravel projektben. Ezt úgy tehetjük meg, hogy hozzáadjuk BroadcastServiceProvidert a `config/app.php`-hoz:

// config/app.php
​
return [
    // ...
​
    'providers' => [
        //...
​
        // Enable default broadcast service provider
        App\Providers\BroadcastServiceProvider::class,
​
        // ...
    ],
​
    // ...
];

 

Események küldése

Most, hogy a broadcastot és a Websocket szervert beállítottuk a Laravelben, megkezdhetjük az első események küldését az alkalmazásból. Szerencsére ez bonyolultabbnak hangzik, mint amilyen.


Esemény létrehozása a ShouldBroadcast segítségével

Ahhoz, hogy egy eseményt Websocketen keresztül közvetítsünk az ügyfélnek, csak az Event osztályainkat kell kibővítenünk a Laravel által biztosított ShouldBroadcast osztállyal. A többit a Laravel automatikusan intézi. Ha – mint esetünkben – azt szeretnénk elérni, hogy az esemény ne minden felhasználóhoz, hanem csak egy meghatározott bejelentkezett felhasználóhoz jusson el, ezt a `broadcastOn` metódusban definiálhatja. Esetünkben a `BackgroundJob` objektum `user_id`-jét használjuk arra, hogy az eseményt csak az adott felhasználói azonosítóval rendelkező felhasználó privát csatornájára küldjük (például `App.Models.User.2348792`).

// app/Events/BackgroundJob.php
​
use App\Models\BackgroundJob;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
​
class BackgroundJobUpdated implements ShouldBroadcast
{
    public function __construct(
        public BackgroundJob $backgroundJob
    ) {}
​
    public function broadcastOn()
    {
        return new PrivateChannel('App.Models.User.' . $this->backgroundJob->user_id);
    }
​
    // ...
}

Ha a WebSocket kapcsolat megfelelően van konfigurálva, akkor ezek az adatok azonnal elküldésre kerülnek a csatlakoztatott WebSocket ügyfeleknek.

Események fogadása

Aki A-t mond, annak B-t is kell mondania – aki küld, annak kapnia is kell. Itt jön képbe a Laravel WebSocket szerver megfelelője – a Laravel echo Javascript kliens. Ez egy karcsú Javascript-könyvtár, amely a socket.io vagy a pusher Javascript klienssel is működtethető. Példánkban az echo klienst használjuk a pusher Javascript klienssel.

Az echo kliens és a pusher könyvtár a webes kezelőfelületen (például egy kis SPA NuxtJS-szel) telepítve van a következő parancsokkal:

npm install laravel-echo pusher-js

Ezt követően néhány metódushívással WebSocket kapcsolat létesíthető a Laravel WebSocket szerverrel:

const echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.PUSHER_KEY,
    wsHost: process.env.PUSHER_HOST,
    wsPort: 443,
    forceTLS: true,
})
​
echo.private(`App.Models.User.${currentUser.id}`)
    .listen('BackgroundJobUpdated', event => console.log(event));

Az Echo kliens inicializálása után könnyen meghatározhatjuk azokat a csatornákat, amelyeket meg akarunk hallgatni az új eseményekhez. A fenti példában csak egy "BackgroundJobUpdated" esemény kimenetét naplózzuk a konzolra, miután a háttérrendszer elküldte azt az aktuális felhasználónak.

Hitelesítés és privát csatornák

Elvileg minden kliens először bejelentkezhet a Laravel WebSocket szerverre. A WebSocket kliensnek azonban hitelesítenie kell magát, amikor csatlakozik a privát üzenetekhez.

Ebből a célból a Laravel WebSockets biztosítja az útvonalat/közvetítést/hitelesítést. A Laravel echo kliens a kapcsolat létrejöttekor automatikusan megpróbálja hitelesíteni a WebSocket felhasználót a privát csatornák használatához.

Ez a BroadcastServiceProvider rendszerindítási metódusában határozható meg.

// app/Providers/BroadcastServiceProvider.php
public function boot()
{
    Broadcast::routes();
​
    require base_path('routes/channels.php');
}

A csatornák lehetnek például privát csatornák, például a felhasználói adatok frissítésére szolgáló csatorna. Az alábbi konfigurációval biztosítjuk, hogy a bejelentkezett felhasználó csak a felhasználói adataival és a neki szánt frissítésekkel férhessen hozzá a broadcast csatornához. Ebben az esetben a csatornanév végén található felhasználói azonosítónak meg kell egyeznie a bejelentkezett felhasználó azonosítójával - egyszerű, de hatékony!

// routes/channels.php
​
use Illuminate\Support\Facades\Broadcast;

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

Török Ádám

Török Ádám

Fejlesztő