Description
Starting from version 4.x, Workerman has strengthened its support for HTTP services. It introduces request classes, response classes, session classes, and SSE. If you want to use Workerman's HTTP service, it is highly recommended to use Workerman 4.x or higher.
Note that all the following usages are for Workerman 4.x version and are not compatible with Workerman 3.x.
Notice
- You are not allowed to send multiple responses in one request unless you are sending a chunk or SSE response, meaning you cannot call
$connection->send()multiple times in one request. - Each request must ultimately call
$connection->send()to send a response; otherwise, the client will keep waiting.
Quick Response
When you do not need to change the HTTP status code (default 200), or customize headers, cookies, you can directly send a string to the client to complete the response.
Example
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)
{
// Directly send this is body to the client
$connection->send("this is body");
};
// Run worker
Worker::runAll();
Change Status Code
When you need to customize the status code, headers, and cookies, you need to use the Workerman\Protocols\Http\Response response class. For example, the following example returns a 404 status code when accessing the path /404, with the body content <h1>Sorry, file does not exist</h1>.
Example
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>Sorry, file does not exist</h1>'));
} else {
$connection->send('this is body');
}
};
// Run worker
Worker::runAll();
To change the status code after the Response class has been initialized, use the following method.
$response = new Response(200);
$response->withStatus(404);
$connection->send($response);
Send Header
Similarly, sending headers requires the use of the Workerman\Protocols\Http\Response response class.
Example
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 Value'
], 'this is body');
$connection->send($response);
};
// Run worker
Worker::runAll();
To add or change headers after the Response class has been initialized, use the following method.
$response = new Response(200);
// Add or change a header
$response->header('Content-Type', 'text/html');
// Add or change multiple headers
$response->withHeaders([
'Content-Type' => 'application/json',
'X-Header-One' => 'Header Value'
]);
$connection->send($response);
Redirect
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();
Send Cookie
Similarly, sending cookies requires the use of the Workerman\Protocols\Http\Response response class.
Example
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);
};
// Run worker
Worker::runAll();
Send File
Similarly, sending files requires the use of the Workerman\Protocols\Http\Response response class.
Send files using the following method.
$response = (new Response())->withFile($file);
$connection->send($response);
- Workerman supports sending very large files.
- For large files (over 2MB), Workerman does not read the entire file into memory at once. Instead, it reads the file in chunks at appropriate moments and sends it.
- Workerman optimizes the file reading and sending speed based on the client's receiving speed, ensuring the fastest file sending while minimizing memory usage.
- Data sending is non-blocking and will not affect the processing of other requests.
- An automatic
Last-Modifiedheader will be added when sending a file, allowing the server to determine whether to send a 304 response on the next request to save file transmission and improve performance. - Sent files will be automatically sent to the browser with the appropriate
Content-Typeheader. - If the file does not exist, a 404 response will automatically be returned.
Example
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';
// Check if-modified-since header to determine if the file has been modified
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();
// If the file hasn't been modified, return 304
if ($modified_time === $if_modified_since) {
$connection->send(new Response(304));
return;
}
}
// If the file has been modified or there is no if-modified-since header, send the file
$response = (new Response())->withFile($file);
$connection->send($response);
};
// Run worker
Worker::runAll();
Send HTTP Chunk Data
- You must first send a Response response with the
Transfer-Encoding: chunkedheader to the client. - Use the
Workerman\Protocols\Http\Chunkclass to send subsequent chunk data. - Finally, you must send an empty chunk to terminate the response.
Example
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)
{
// First, send a Response response with the Transfer-Encoding: chunked header
$connection->send(new Response(200, array('Transfer-Encoding' => 'chunked'), 'hello'));
// Send subsequent chunk data using Workerman\Protocols\Http\Chunk class
$connection->send(new Chunk('First chunk of data'));
$connection->send(new Chunk('Second chunk of data'));
$connection->send(new Chunk('Third chunk of data'));
// Finally, send an empty chunk to end the response
$connection->send(new Chunk(''));
};
// Run worker
Worker::runAll();