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év | Technológia | Licensz | Aktualitás | Skálázhatóság | Protokoll |
---|---|---|---|---|---|
Laravel Echo Server | NodeJS | MIT | medium | high | socket.io |
Laravel Websockets | PHP | MIT | high | ok, v2-beta | pusher |
Soketi | C, NodeJS | MIT | medium | top | pusher |
Pusher.com | Saas | commercial | high | top | pusher |
Ably | Saas | commercial | high | top | pusher |
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;
});