Signatur
Beschreibung
Swoole\Server ist die Kernklasse der Swoole-Erweiterung und ermöglicht die Erstellung asynchroner, ereignisgesteuerter TCP- und UDP-Server in PHP. Im Gegensatz zum klassischen synchronen PHP-Ausführungsmodell bleibt der Server dauerhaft im Speicher und verarbeitet Verbindungen über einen Multi-Prozess-/Multi-Worker-Ansatz, was extrem hohe Durchsatzraten und niedrige Latenzen ermöglicht.
Der Server wird über Ereignis-Callbacks (Event-Handler) gesteuert. Typische Callbacks sind onConnect, onReceive, onClose und onStart. Diese werden mit der Methode on() registriert. Erst nach dem Aufruf von start() beginnt der Server, eingehende Verbindungen zu akzeptieren – dieser Aufruf blockiert die weitere Skriptausführung.
Die Klasse unterstützt eine Vielzahl von Protokollen und Funktionen: TCP, UDP, Unix-Domain-Sockets, SSL/TLS-Verschlüsselung, WebSockets (über Swoole\WebSocket\Server), Task-Worker für blockierende Operationen sowie Timer und asynchrone I/O. Über set() lassen sich zahlreiche Serverparameter wie Worker-Anzahl, Backlog-Größe oder Heartbeat-Intervall konfigurieren.
Swoole eignet sich besonders für Microservices, API-Gateway-Implementierungen, Chat-Server, Gaming-Backend und alle Szenarien, in denen PHP-FPM/Apache zu viel Overhead durch Prozess-Spawning erzeugen würden. Die Erweiterung muss separat über PECL installiert werden und ist nicht Bestandteil der PHP-Standardinstallation.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $host Pflicht | string | IP-Adresse oder Hostname, auf dem der Server lauschen soll. 0.0.0.0 für alle Interfaces, 127.0.0.1 für Loopback. Für Unix-Domain-Sockets ein Dateipfad wie unix:/tmp/server.sock. |
|
| $port Pflicht | int | TCP- oder UDP-Port, auf dem der Server lauscht. Ports unter 1024 erfordern Root-Rechte. Bei Unix-Domain-Sockets wird dieser Parameter ignoriert (üblicherweise 0). |
|
| $mode | int | SWOOLE_PROCESS | Betriebsmodus des Servers. SWOOLE_PROCESS (Standard) startet Worker in separaten Prozessen; SWOOLE_BASE führt Worker-Logik im Reactor-Thread aus (niedrigerer Overhead, aber eingeschränkte Funktionalität). |
| $sock_type | int | SWOOLE_SOCK_TCP | Socket-Typ. Mögliche Werte: SWOOLE_SOCK_TCP, SWOOLE_SOCK_TCP6, SWOOLE_SOCK_UDP, SWOOLE_SOCK_UDP6, SWOOLE_UNIX_STREAM oder SWOOLE_UNIX_DGRAM. SSL kann durch bitweises ODER mit SWOOLE_SSL aktiviert werden. |
Beispiele
Einfacher TCP-Echo-Server
<?php
// Voraussetzung: Swoole-Erweiterung installiert (pecl install swoole)
$server = new Swoole\Server('0.0.0.0', 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
// Serverkonfiguration
$server->set([
'worker_num' => 4, // 4 Worker-Prozesse
'max_conn' => 1000, // Maximale gleichzeitige Verbindungen
'heartbeat_check_interval' => 60,
'heartbeat_idle_time' => 120,
]);
// Callback: Neue Verbindung
$server->on('Connect', function (Swoole\Server $server, int $fd, int $reactorId) {
echo "[Connect] Client #{$fd} verbunden (Reactor: {$reactorId})\n";
});
// Callback: Daten empfangen — Echo zurück senden
$server->on('Receive', function (Swoole\Server $server, int $fd, int $reactorId, string $data) {
echo "[Receive] Von Client #{$fd}: " . trim($data) . "\n";
$server->send($fd, 'Echo: ' . $data);
});
// Callback: Verbindung getrennt
$server->on('Close', function (Swoole\Server $server, int $fd) {
echo "[Close] Client #{$fd} getrennt\n";
});
// Server starten (blockiert ab hier)
$server->start();
TCP-Server mit Task-Worker für blockierende Operationen
<?php
// Task-Worker ermöglichen blockierende Aufgaben (z. B. DB-Abfragen)
// ohne den Event-Loop zu blockieren
$server = new Swoole\Server('127.0.0.1', 9502);
$server->set([
'worker_num' => 2,
'task_worker_num' => 4, // Separate Task-Worker-Prozesse
]);
$server->on('Receive', function (Swoole\Server $server, int $fd, int $rid, string $data) {
// Aufgabe an Task-Worker delegieren
$taskId = $server->task([
'fd' => $fd,
'data' => trim($data),
]);
echo "Task #{$taskId} gestartet für Client #{$fd}\n";
});
// Task-Worker: Blockierende Verarbeitung (z. B. sleep als DB-Simulation)
$server->on('Task', function (Swoole\Server $server, int $taskId, int $workerId, mixed $data) {
// Simulierte blockierende Arbeit
$result = strtoupper($data['data']);
sleep(1); // z. B. Datenbankabfrage
$server->finish(['fd' => $data['fd'], 'result' => $result]);
});
// Ergebnis des Task-Workers an Client zurücksenden
$server->on('Finish', function (Swoole\Server $server, int $taskId, mixed $data) {
$server->send($data['fd'], 'Ergebnis: ' . $data['result'] . "\n");
});
$server->on('Connect', function () {});
$server->on('Close', function () {});
$server->start();
UDP-Server mit mehreren Ports (Multi-Port-Listening)
<?php
// Hauptserver auf TCP, zusätzlicher UDP-Port über addlistener()
$server = new Swoole\Server('0.0.0.0', 9503, SWOOLE_PROCESS, SWOOLE_SOCK_TCP);
// Zusätzlichen UDP-Port hinzufügen
$udpPort = $server->addlistener('0.0.0.0', 9504, SWOOLE_SOCK_UDP);
$udpPort->on('Packet', function (Swoole\Server $server, string $data, array $clientInfo) {
echo "UDP-Paket von {$clientInfo['address']}:{$clientInfo['port']}: {$data}\n";
$server->sendto($clientInfo['address'], $clientInfo['port'], 'UDP Echo: ' . $data);
});
$server->on('Connect', function (Swoole\Server $server, int $fd) {
echo "TCP-Client #{$fd} verbunden\n";
});
$server->on('Receive', function (Swoole\Server $server, int $fd, int $rid, string $data) {
$server->send($fd, 'TCP Echo: ' . $data);
});
$server->on('Close', function () {});
$server->on('Start', function (Swoole\Server $server) {
echo "Server gestartet — TCP: 9503, UDP: 9504\n";
});
$server->start();
// Wichtig · Fallstricke
Installation: Swoole ist keine PHP-Standarderweiterung. Installation via pecl install swoole oder über den Paketmanager (z. B. apt install php-swoole). Danach in der php.ini aktivieren: extension=swoole.
Nicht mit PHP-FPM/Apache mischen: Swoole\Server ist für den CLI-Betrieb konzipiert. Der Aufruf von start() blockiert dauerhaft. Der Server sollte als eigenständiger Dienst (z. B. via systemd) betrieben werden.
Prozessmodell und gemeinsamer Speicher: Im SWOOLE_PROCESS-Modus laufen Worker in getrennten Prozessen. Globale Variablen und Objekte sind nicht automatisch zwischen Prozessen geteilt. Für geteilten Zustand stehen Swoole\Table, Swoole\Atomic oder externe Speicher (Redis, Memcached) zur Verfügung.
Sicherheit: SSL/TLS kann durch Kombination von SWOOLE_SSL mit dem Socket-Typ sowie den Optionen ssl_cert_file und ssl_key_file in set() aktiviert werden. Ohne TLS sollte der Server hinter einem Reverse-Proxy (nginx) betrieben werden.
PHP-Kompatibilität: Swoole 5.x unterstützt PHP 8.0 und höher. Ältere Versionen unterstützen PHP 7.x. Manche PHP-Funktionen (z. B. header(), echo außerhalb von Callbacks) funktionieren im Server-Kontext nicht wie erwartet.