Signatur
Beschreibung
Swoole\Coroutine\Client ist ein asynchroner Netzwerk-Client, der innerhalb von Swoole-Koroutinen verwendet wird und blockierende Netzwerkoperationen (Verbinden, Senden, Empfangen) automatisch in nicht-blockierende, koroutinenfreundliche Aufrufe umwandelt. Während eine Operation wartet (z. B. auf eine Serverantwort), gibt die Koroutine die Kontrolle ab, sodass andere Koroutinen ausgeführt werden können.
Der Client unterstützt die Protokolle TCP (SWOOLE_SOCK_TCP), UDP (SWOOLE_SOCK_UDP), TCP6 (SWOOLE_SOCK_TCP6) und UDP6 (SWOOLE_SOCK_UDP6) sowie Unix-Domain-Sockets. Er eignet sich besonders für Dienste, die viele gleichzeitige Verbindungen zu externen Servern (z. B. Datenbanken, APIs, Caches) aufbauen müssen, ohne den gesamten Prozess zu blockieren.
Typische Verwendungsszenarien sind HTTP-Clients, Datenbank-Proxies, Microservice-Kommunikation und alle Situationen, in denen klassisches Socket-Programmieren im synchronen Stil innerhalb einer hochperformanten, koroutinenbasierten Anwendung gewünscht wird. Der Programmcode liest sich dabei wie synchrones PHP, arbeitet aber vollständig nicht-blockierend.
Instanzen dieses Clients dürfen nur innerhalb einer Koroutine erzeugt und verwendet werden. Außerhalb einer Swoole-Koroutine (z. B. im normalen PHP-Skript ohne Server-Kontext) ist das Verhalten undefiniert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | int | Gibt den Socket-Typ an. Mögliche Werte: SWOOLE_SOCK_TCP, SWOOLE_SOCK_TCP6, SWOOLE_SOCK_UDP, SWOOLE_SOCK_UDP6, SWOOLE_SOCK_UNIX_STREAM oder SWOOLE_SOCK_UNIX_DGRAM. Für verschlüsselte Verbindungen kann SWOOLE_SOCK_TCP | SWOOLE_SSL übergeben werden. |
Beispiele
Einfache TCP-Verbindung zu einem Echo-Server
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\Client;
Coroutine\run(function () {
$client = new Client(SWOOLE_SOCK_TCP);
// Verbindungsaufbau (nicht-blockierend dank Koroutine)
if (!$client->connect('127.0.0.1', 9501, 1.0)) {
echo 'Verbindung fehlgeschlagen: ' . $client->errCode . PHP_EOL;
return;
}
// Daten senden
$client->send('Hallo, Server!');
// Antwort empfangen (wartet nicht-blockierend)
$response = $client->recv();
echo 'Antwort vom Server: ' . $response . PHP_EOL;
$client->close();
});
Mehrere gleichzeitige HTTP-Anfragen mit Koroutinen
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\Client;
Coroutine\run(function () {
$urls = [
['host' => 'httpbin.org', 'path' => '/get?foo=bar'],
['host' => 'httpbin.org', 'path' => '/get?hello=world'],
];
$waitGroup = new Coroutine\WaitGroup();
$results = [];
foreach ($urls as $i => $url) {
$waitGroup->add();
Coroutine::create(function () use ($url, $i, $waitGroup, &$results) {
$client = new Client(SWOOLE_SOCK_TCP);
$client->set(['timeout' => 5]);
if ($client->connect($url['host'], 80, 5)) {
$request = "GET {$url['path']} HTTP/1.1\r\n";
$request .= "Host: {$url['host']}\r\n";
$request .= "Connection: close\r\n\r\n";
$client->send($request);
$response = '';
while (($chunk = $client->recv()) !== false && $chunk !== '') {
$response .= $chunk;
}
$client->close();
$results[$i] = substr($response, 0, 120) . '...';
} else {
$results[$i] = 'Fehler: ' . $client->errCode;
}
$waitGroup->done();
});
}
$waitGroup->wait();
foreach ($results as $idx => $res) {
echo "Ergebnis #{$idx}: {$res}" . PHP_EOL;
}
});
SSL/TLS-Verbindung zu einem HTTPS-Endpunkt
<?php
use Swoole\Coroutine;
use Swoole\Coroutine\Client;
Coroutine\run(function () {
// SWOOLE_SOCK_TCP | SWOOLE_SSL aktiviert TLS
$client = new Client(SWOOLE_SOCK_TCP | SWOOLE_SSL);
$client->set([
'ssl_verify_peer' => true,
'ssl_cafile' => '/etc/ssl/certs/ca-certificates.crt',
]);
if (!$client->connect('example.com', 443, 3.0)) {
echo 'TLS-Verbindung fehlgeschlagen: ' . $client->errMsg . PHP_EOL;
return;
}
$client->send("GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
$response = $client->recv();
echo substr($response, 0, 200) . PHP_EOL;
$client->close();
});
// Wichtig · Fallstricke
Nur innerhalb von Koroutinen verwenden: Swoole\Coroutine\Client darf ausschließlich innerhalb einer laufenden Koroutine instanziiert und verwendet werden. Andernfalls kommt es zu einem fatalen Fehler oder undefiniertem Verhalten.
- Timeouts: Der dritte Parameter von
connect()sowie die Optiontimeoutinset()sollten immer gesetzt werden, um hängende Verbindungen zu vermeiden. - Fehlerbehandlung: Prüfen Sie nach
connect(),send()undrecv()stets den Rückgabewert sowie$client->errCodeund$client->errMsg. - Protokollerkennung: Für strukturierte Protokolle (z. B. HTTP, MQTT) empfiehlt sich die Konfiguration von
open_length_checkoderopen_eof_checküberset(), um vollständige Pakete zu empfangen. - Ressourcen: Nach Gebrauch immer
close()aufrufen, um Dateideskriptoren freizugeben. - Alternative: Für reine HTTP-Anfragen ist
Swoole\Coroutine\Http\Clientkomfortabler, da er das HTTP-Protokoll vollständig kapselt.