Documentazione
A partire dalla versione 4.x, Workerman ha potenziato il supporto ai servizi HTTP. È stato introdotto una classe di richiesta, una classe di risposta, una classe di sessione e anche (SSE)[SSE.html]. Se si desidera utilizzare il servizio HTTP di Workerman, si consiglia vivamente di utilizzare la versione 4.x di Workerman o versioni successive.
Si noti che di seguito si fa riferimento all'uso della versione 4.x di Workerman e non è compatibile con la versione 3.x.
Note
- A meno che non si stiano inviando risposte chunk o SSE, non è consentito inviare più di una volta una risposta in una singola richiesta, ovvero non è consentito chiamare
$connection->send()
più volte in una singola richiesta. - Ogni richiesta deve alla fine chiamare una volta
$connection->send()
per inviare la risposta, altrimenti il client rimarrà in attesa.
Risposta rapida
Quando non è necessario modificare il codice di stato HTTP (impostato di default a 200), o personalizzare l'header o i cookie, è possibile inviare direttamente una stringa al client per completare la risposta.
Esempio
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)
{
// Invia direttamente "this is body" al client
$connection->send("this is body");
};
// Avvia il worker
Worker::runAll();
Modifica del codice di stato
Quando è necessario personalizzare il codice di stato, l'header o i cookie, è necessario utilizzare la classe di risposta Workerman\Protocols\Http\Response
. Ad esempio, l'esempio seguente restituisce il codice di stato 404 e il contenuto del corpo è <h1>Scusa, il file non esiste</h1>
quando si accede al percorso /404
.
Esempio
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>Scusa, il file non esiste</h1>'));
} else {
$connection->send('this is body');
}
};
// Avvia il worker
Worker::runAll();
Una volta inizializzata la classe Response
, è possibile modificare il codice di stato utilizzando il metodo seguente.
$response = new Response(200);
$response->withStatus(404);
$connection->send($response);
Invio header
Anche per l'invio dell'header è necessario utilizzare la classe di risposta Workerman\Protocols\Http\Response
.
Esempio
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' => 'Valore dell'header'
], 'this is body');
$connection->send($response);
};
// Avvia il worker
Worker::runAll();
Una volta inizializzata la classe Response
, è possibile aggiungere o modificare l'header utilizzando il metodo seguente.
$response = new Response(200);
// Aggiunge o modifica un header
$response->header('Content-Type', 'text/html');
// Aggiunge o modifica più header
$response->withHeaders([
'Content-Type' => 'application/ json',
'X-Header-One' => 'Valore dell'header'
]);
$connection->send($response);
Redirezione
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);
};
// Avvia il worker
Worker::runAll();
Invio cookie
Anche per l'invio dei cookie è necessario utilizzare la classe di risposta Workerman\Protocols\Http\Response
.
Esempio
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);
};
// Avvia il worker
Worker::runAll();
Invio di file
Anche per l'invio di file è necessario utilizzare la classe di risposta Workerman\Protocols\Http\Response
.
Per inviare un file, è possibile utilizzare il seguente metodo
$response = (new Response())->withFile($file);
$connection->send($response);
- Workerman supporta l'invio di file di grandi dimensioni
- Per i file di grandi dimensioni (oltre 2 MB), Workerman non carica l'intero file in memoria una sola volta, ma legge e invia il file in segmenti in momenti opportuni
- Workerman ottimizza la velocità di lettura del file in base alla velocità con cui il client riceve i dati, garantendo l'invio più veloce possibile riducendo al minimo l'uso della memoria
- L'invio dei dati è non bloccante e non interferisce con la gestione di altre richieste
- Quando si invia un file, viene automaticamente aggiunto l'header
Last-Modified
per consentire al server di verificare se inviare una risposta 304 la prossima volta per risparmiare trasferimento dati e aumentare le prestazioni - Il file inviato utilizza automaticamente l'header
Content-Type
appropriato per essere inviato al browser - Se il file non esiste, viene automaticamente gestito come risposta 404
Esempio
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 = '/il/tuo/percorso/del/file';
// Verifica l'header if-modified-since per determinare se il file è stato modificato
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();
// Se il file non è stato modificato restituisci una risposta 304
if ($modified_time === $if_modified_since) {
$connection->send(new Response(304));
return;
}
}
// Se il file è stato modificato o non c'è l'header if-modified-since, invia il file
$response = (new Response())->withFile($file);
$connection->send($response);
};
// Avvia il worker
Worker::runAll();
Invio di dati http chunk
- È necessario inviare prima una risposta
Response
con l'headerTransfer-Encoding: chunked
al client - Per inviare dati chunk successivi, utilizzare la classe
Workerman\Protocols\Http\Chunk
- Infine, è necessario inviare un chunk vuoto per terminare la risposta
Esempio
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)
{
// Invia prima una risposta `Response` con l'header `Transfer-Encoding: chunked`
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello'));
// Utilizza la classe `Workerman\Protocols\Http\Chunk` per inviare dati chunk successivi
$connection->send(new Chunk('Primo blocco di dati'));
$connection->send(new Chunk('Secondo blocco di dati'));
$connection->send(new Chunk('Terzo blocco di dati'));
// Alla fine è necessario inviare un chunk vuoto per terminare la risposta
$connection->send(new Chunk(''));
};
// Avvia il worker
Worker::runAll();