Start · Sprachen · PHP · Referenz · Swoole\Server

Swoole\Server

Klasse

Implementiert einen hochperformanten asynchronen TCP/UDP-Server auf Basis der Swoole-Erweiterung.

seit PHP 1.0.0 Kategorie: misc

Signatur

class Swoole\Server

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();
[Start] Server läuft auf 0.0.0.0:9501 [Connect] Client #1 verbunden (Reactor: 0) [Receive] Von Client #1: Hallo Swoole [Close] Client #1 getrennt

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();
Task #0 gestartet für Client #1

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();
Server gestartet — TCP: 9503, UDP: 9504

// 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.