Start · Sprachen · PHP · Referenz · Swoole\WebSocket\Server

Swoole\WebSocket\Server

Klasse

Implementiert einen asynchronen, hochperformanten WebSocket-Server auf Basis der Swoole-Erweiterung.

seit PHP 1.7.14 Kategorie: misc

Signatur

class Swoole\WebSocket\Server extends Swoole\Http\Server

Beschreibung

Swoole\WebSocket\Server erweitert Swoole\Http\Server und ermöglicht den Aufbau eines vollständig asynchronen WebSocket-Servers in PHP. Der Server unterstützt bidirektionale Echtzeitkommunikation zwischen dem Server und verbundenen Clients über das WebSocket-Protokoll (RFC 6455).

Typische Anwendungsfälle sind Echtzeit-Chats, Live-Benachrichtigungen, Multiplayer-Spiele, Dashboards mit Live-Daten oder jede Anwendung, die eine dauerhafte, bidirektionale Verbindung zwischen Server und Browser benötigt. Anders als beim klassischen HTTP-Request-Response-Modell bleibt die Verbindung offen, was Latenz drastisch reduziert.

Der Server wird über Event-Callbacks gesteuert: onOpen wird beim Verbindungsaufbau ausgelöst, onMessage beim Empfang einer Nachricht und onClose beim Trennen der Verbindung. Nachrichten können sowohl als Text- als auch als Binärframes gesendet werden. Intern verwaltet Swoole alle Verbindungen über einen File-Descriptor ($fd), der als eindeutiger Bezeichner für jeden verbundenen Client dient.

Da Swoole\WebSocket\Server von Swoole\Http\Server erbt, können reguläre HTTP-Anfragen und WebSocket-Verbindungen auf demselben Port gleichzeitig bedient werden, indem sowohl ein onRequest- als auch ein onMessage-Handler registriert werden.

Parameter

Name Typ Default Beschreibung
$host Pflicht string Die IP-Adresse oder der Hostname, auf der/dem der Server lauschen soll, z. B. '0.0.0.0' für alle Interfaces oder '127.0.0.1' für Localhost.
$port Pflicht int Der TCP-Port, auf dem der Server eingehende Verbindungen akzeptiert, z. B. 9501.
$mode int SWOOLE_PROCESS Der Betriebsmodus des Servers. Mögliche Werte: SWOOLE_PROCESS (Standard, Multi-Process) oder SWOOLE_BASE (Reactor-Modus ohne Master-Prozess).
$sockType int SWOOLE_SOCK_TCP Socket-Typ. Standard ist SWOOLE_SOCK_TCP. Für TLS/SSL kann SWOOLE_SOCK_TCP | SWOOLE_SSL angegeben werden.

Beispiele

Einfacher WebSocket-Echo-Server

<?php
// server.php — Starten mit: php server.php
$server = new Swoole\WebSocket\Server('0.0.0.0', 9501);

$server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) {
    echo "Neue Verbindung: fd={$request->fd}\n";
});

$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
    echo "Empfangen von fd={$frame->fd}: {$frame->data}\n";
    // Nachricht zurück an den Sender schicken (Echo)
    $server->push($frame->fd, 'Echo: ' . $frame->data);
});

$server->on('close', function (Swoole\WebSocket\Server $server, int $fd) {
    echo "Verbindung getrennt: fd={$fd}\n";
});

$server->start();
Neue Verbindung: fd=1 Empfangen von fd=1: Hallo Welt Verbindung getrennt: fd=1

WebSocket-Server mit HTTP-Fallback und Broadcast

<?php
$server = new Swoole\WebSocket\Server('0.0.0.0', 9502);

// Konfiguration
$server->set([
    'worker_num'    => 4,
    'max_conn'      => 10000,
    'heartbeat_idle_time'      => 60,
    'heartbeat_check_interval' => 30,
]);

// Reguläre HTTP-Anfragen bedienen
$server->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response) {
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end('<h1>WebSocket-Server läuft</h1>');
});

$server->on('open', function (Swoole\WebSocket\Server $server, Swoole\Http\Request $request) {
    echo "Client verbunden: fd={$request->fd}, IP={$request->server['remote_addr']}\n";
    $server->push($request->fd, json_encode(['type' => 'welcome', 'message' => 'Willkommen!']));
});

$server->on('message', function (Swoole\WebSocket\Server $server, Swoole\WebSocket\Frame $frame) {
    $data = json_decode($frame->data, true);

    if (isset($data['broadcast']) && $data['broadcast']) {
        // Nachricht an alle verbundenen Clients senden
        foreach ($server->connections as $fd) {
            if ($server->isEstablished($fd)) {
                $server->push($fd, json_encode([
                    'type'    => 'broadcast',
                    'from'    => $frame->fd,
                    'message' => $data['message'] ?? '',
                ]));
            }
        }
    } else {
        // Nur an den Absender antworten
        $server->push($frame->fd, json_encode([
            'type'    => 'reply',
            'message' => 'Empfangen: ' . ($data['message'] ?? ''),
        ]));
    }
});

$server->on('close', function (Swoole\WebSocket\Server $server, int $fd) {
    echo "Client getrennt: fd={$fd}\n";
});

$server->start();

// Wichtig · Fallstricke

Sicherheitshinweise: Standardmäßig führt Swoole\WebSocket\Server keinen Origin-Check durch. Es empfiehlt sich, im onOpen-Callback den Origin-Header aus $request->header['origin'] zu validieren und unbekannte Verbindungen mit $server->disconnect($request->fd, 1008) zu schließen, um Cross-Site-WebSocket-Hijacking zu verhindern.

SSL/TLS: Für Produktivumgebungen sollte der Server mit SWOOLE_SOCK_TCP | SWOOLE_SSL gestartet und ssl_cert_file sowie ssl_key_file in der Konfiguration gesetzt werden. Alternativ kann ein Reverse-Proxy (nginx) die TLS-Terminierung übernehmen.

Verbindungsprüfung: Vor dem Senden einer Nachricht immer mit $server->isEstablished($fd) prüfen, ob die WebSocket-Verbindung noch aktiv ist, um Fehler beim Senden an bereits getrennte Clients zu vermeiden.

Achtung: Swoole läuft als CLI-SAPI und ist nicht für traditionelle PHP-FPM/Apache-Deployments geeignet. Der Server muss als dauerhaft laufender Prozess betrieben werden (z. B. mit Supervisor oder systemd).