Hinweise
Workerman hat mit der Version 4.x die Unterstützung für HTTP-Services verbessert. Es wurden Klassen für Anfragen, Antworten, Sessions sowie SSE eingeführt. Wenn Sie die HTTP-Dienste von Workerman verwenden möchten, wird dringend empfohlen, Workerman 4.x oder eine spätere Version zu verwenden.
Bitte beachten Sie, dass die folgenden Beispiele für die Version Workerman 4.x gelten und nicht mit Workerman 3.x kompatibel sind.
Wichtig
- Es ist nicht erlaubt, mehrere Antworten innerhalb einer Anfrage zu senden, es sei denn, es handelt sich um chunked oder SSE-Antworten, das heißt,
$connection->send()darf nicht mehrmals innerhalb einer Anfrage aufgerufen werden. - Jede Anfrage muss letztendlich einmal
$connection->send()aufrufen, um eine Antwort zu senden, andernfalls wird der Client weiterhin warten.
Schnelle Antwort
Wenn der HTTP-Statuscode (standardmäßig 200) oder benutzerdefinierte Header und Cookies nicht geändert werden müssen, kann einfach ein String an den Client gesendet werden, um die Antwort abzuschließen.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
// Direkt "this is body" an den Client senden
$connection->send("this is body");
};
// Arbeiter starten
Worker::runAll();
Statuscode ändern
Wenn benutzerdefinierte Statuscodes, Header oder Cookies verwendet werden müssen, sollte die Klasse Workerman\Protocols\Http\Response verwendet werden. Im folgenden Beispiel wird bei einem Zugriff auf den Pfad /404 der Statuscode 404 zurückgegeben, und der Body-Inhalt ist <h1>Entschuldigung, Datei nicht gefunden</h1>.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
if ($request->path() === '/404') {
$connection->send(new Response(404, [], '<h1>Entschuldigung, Datei nicht gefunden</h1>'));
} else {
$connection->send('this is body');
}
};
// Arbeiter starten
Worker::runAll();
Wenn die Response-Klasse bereits initialisiert wurde, kann der Statuscode wie folgt geändert werden.
$response = new Response(200);
$response->withStatus(404);
$connection->send($response);
Header senden
Um Header zu senden, muss ebenfalls die Klasse Workerman\Protocols\Http\Response verwendet werden.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$response = new Response(200, [
'Content-Type' => 'text/html',
'X-Header-One' => 'Header-Wert'
], 'this is body');
$connection->send($response);
};
// Arbeiter starten
Worker::runAll();
Wenn die Response-Klasse bereits initialisiert wurde, können Header wie folgt hinzugefügt oder geändert werden.
$response = new Response(200);
// Einen Header hinzufügen oder ändern
$response->header('Content-Type', 'text/html');
// Mehrere Header hinzufügen oder ändern
$response->withHeaders([
'Content-Type' => 'application/json',
'X-Header-One' => 'Header-Wert'
]);
$connection->send($response);
Weiterleitung
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$location = '/test_location';
$response = new Response(302, ['Location' => $location]);
$connection->send($response);
};
Worker::runAll();
Cookie senden
Um Cookies zu senden, sollte ebenfalls die Klasse Workerman\Protocols\Http\Response verwendet werden.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$response = new Response(200, [], 'this is body');
$response->cookie('name', 'tom');
$connection->send($response);
};
// Arbeiter starten
Worker::runAll();
Datei senden
Um Dateien zu senden, muss ebenfalls die Klasse Workerman\Protocols\Http\Response verwendet werden.
Um eine Datei zu senden, verwenden Sie die folgende Methode:
$response = (new Response())->withFile($file);
$connection->send($response);
- Workerman unterstützt das Senden von sehr großen Dateien.
- Bei großen Dateien (über 2 MB) wird Workerman die gesamte Datei nicht auf einmal in den Speicher lesen, sondern in geeigneten Zeitfenstern segmentiert lesen und senden.
- Workerman optimiert die Dateilesegeschwindigkeit basierend auf der Empfangsgeschwindigkeit des Clients, um die Dateien so schnell wie möglich zu senden und gleichzeitig den Speicherbedarf zu minimieren.
- Der Datentransfer ist nicht blockierend und beeinträchtigt nicht die Verarbeitung anderer Anfragen.
- Beim Senden von Dateien wird automatisch der
Last-Modified-Header hinzugefügt, damit der Server beim nächsten Request entscheiden kann, ob eine 304-Antwort gesendet werden soll, um die Dateitransfergeschwindigkeit zu verbessern. - Die gesendete Datei wird automatisch mit dem geeigneten
Content-Type-Header an den Browser gesendet. - Wenn die Datei nicht existiert, wird automatisch eine 404-Antwort gesendet.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
$file = '/your/path/of/file';
// Überprüfen des if-modified-since-Headers, um zu bestimmen, ob die Datei geändert wurde
if (!empty($if_modified_since = $request->header('if-modified-since'))) {
$modified_time = date('D, d M Y H:i:s', filemtime($file)) . ' ' . \date_default_timezone_get();
// Wenn die Datei nicht geändert wurde, senden Sie 304 zurück
if ($modified_time === $if_modified_since) {
$connection->send(new Response(304));
return;
}
}
// Wenn die Datei geändert wurde oder kein if-modified-since-Header vorhanden ist, senden Sie die Datei
$response = (new Response())->withFile($file);
$connection->send($response);
};
// Arbeiter starten
Worker::runAll();
HTTP Chunk-Daten senden
- Zuerst muss eine Antwort mit dem Header
Transfer-Encoding: chunkedan den Client gesendet werden. - Verwenden Sie für die nachfolgenden Chunk-Daten die Klasse
Workerman\Protocols\Http\Chunk. - Schließlich muss ein leerer Chunk gesendet werden, um die Antwort zu beenden.
Beispiel
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Protocols\Http\Chunk;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8080');
$worker->onMessage = function(TcpConnection $connection, Request $request)
{
// Zuerst eine Antwort mit dem Header Transfer-Encoding: chunked senden
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello'));
// Nachfolgende Chunk-Daten verwenden die Klasse Workerman\Protocols\Http\Chunk
$connection->send(new Chunk('Erster Datenabschnitt'));
$connection->send(new Chunk('Zweiter Datenabschnitt'));
$connection->send(new Chunk('Dritter Datenabschnitt'));
// Schließlich muss ein leerer Chunk gesendet werden, um die Antwort zu beenden
$connection->send(new Chunk(''));
};
// Arbeiter starten
Worker::runAll();