Signatur
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();
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).