Join 4,000+ others and never miss out on new tips, tutorials, and more.
4.x is outdated, please check the latest version 22.x
Latest version:
pecl install openswoole-22.1.2
The Swoole\HTTP\Server
class inherits from the class Swoole\Server
. It is a complete implementation of a HTTP server using the built-in Swoole TCP/UDP server. You will notice that the Swoole HTTP Server has a lot of similarities with the Swoole TCP/UDP server, sharing the same API and some configuration options. They also share the same process model, to learn more about the Server itself, you should also read the Server documentation.
The Swoole HTTP Server is designed to be run from the PHP CLI only
Swoole has a built-in HTTP server that you can run directly from a PHP script, something like server.php
. You have a full HTTP server ready to run in production from the PHP CLI. With only a few lines of code you get a high-performance, high concurrency, asynchronous HTTP server in PHP.
Let's go through a quick start example so you can get a server up and running to test it out.
The first thing we need is a HTTP server instance, so we can create one here while setting the IP and port to listen on.
<?php
$server = new Swoole\HTTP\Server("127.0.0.1", 9501);
When we have a server instance, we can use the set
method to configure the server the way we need (more on server configuration later).
<?php
$server->set([
'worker_num' => 4, // The number of worker processes to start
'task_worker_num' => 4 // The amount of task workers to start
'backlog' => 128, // TCP backlog connection number
]);
As with a lot of things in Swoole, the server runs an event loop and we need to response to those events, this is where we register our main callbacks to interact with the event loop when these events are triggered. There are more events but these are the main ones to consider for now.
<?php
// Triggered when new worker processes starts
$server->on("WorkerStart", function($server, $workerId)
{
// ...
});
// Triggered when the HTTP Server starts, connections are accepted after this callback is executed
$server->on("Start", function($server, $workerId)
{
// ...
});
// The main HTTP server request callback event, entry point for all incoming HTTP requests
$server->on('Request', function(Swoole/Server/Request $request, Swoole/Server/Response $response)
{
$response->end('<h1>Hello World!</h1>');
});
// Triggered when the server is shutting down
$server->on("Shutdown", function($server, $workerId)
{
// ...
});
// Triggered when worker processes are being stopped
$server->on("WorkerStop", function($server, $workerId)
{
// ...
});
There are four types of callback functions
Finally once we have setup our server and registered the event callbacks, this line of code actually starts the server. Place the code inside a PHP file like server.php
and execute the script on the CLI, php server.php
. Then head over to the browser and connect to 127.0.0.1:9501
to see the result.
<?php
$server->start();
See Swoole HTTP Server Working Example for the full code.
Swoole\HTTP\Server::__construct
Swoole\HTTP\Server->set
Swoole\HTTP\Server->on
Swoole\HTTP\Server->listen
Swoole\HTTP\Server->addListener
Swoole\HTTP\Server->addProcess
Swoole\Server->addTimer
Swoole\HTTP\Server->start
Swoole\HTTP\Server->reload
Swoole\HTTP\Server->stop
Swoole\HTTP\Server->shutdown
Swoole\HTTP\Server->tick
Swoole\HTTP\Server->after
Swoole\HTTP\Server->defer
Swoole\Server->clearTimer
Swoole\HTTP\Server->close
Swoole\HTTP\Server->send
Swoole\HTTP\Server->sendfile
Swoole\HTTP\Server->sendto
Swoole\HTTP\Server->sendwait
Swoole\HTTP\Server->sendMessage
Swoole\HTTP\Server->exist
Swoole\HTTP\Server->pause
Swoole\HTTP\Server->resume
Swoole\Server->getCallback
Swoole\HTTP\Server->getClientInfo
Swoole\HTTP\Server->getClientList
Swoole\HTTP\Server->bind
Swoole\HTTP\Server->stats
Swoole\Server->task
Swoole\Server->taskWait
Swoole\Server->taskWaitMulti
Swoole\Server->taskCo
Swoole\HTTP\Server->finish
Swoole\HTTP\Server->heartbeat
Swoole\HTTP\Server->getLastError
Swoole\HTTP\Server->getSocket
Swoole\HTTP\Server->protect
Swoole\Server->confirm
Swoole\Server->getReceivedTime
Swoole\Server->getWorkerId
Swoole\Server->getWorkerPid
Swoole\Server->getWorkerStatus
Swoole\Server->getManagerPid
Swoole\Server->getMasterPid
Server Reaction Events
Swoole\Server->on('Start', fn)
Swoole\Server->on('Shutdown', fn)
Swoole\Server->on('WorkerStart', fn)
Swoole\Server->on('WorkerStop', fn)
Swoole\Server->on('WorkerExit', fn)
Swoole\Server->on('Packet', fn)
Swoole\Server->on('Close', fn)
Swoole\Server->on('Task', fn)
Swoole\Server->on('Finish', fn)
Swoole\Server->on('Timer', fn)
Swoole\Server->on('PipeMessage', fn)
Swoole\Server->on('WorkerError', fn)
Swoole\Server->on('ManagerStart', fn)
Swoole\Server->on('ManagerStop', fn)
Swoole\Server->on('BeforeReload', fn)
Swoole\Server->on('AfterReload', fn)
Main HTTP Server Event
Running a HTTP server compared to the normal Swoole TCP/UDP server, we get access to the on Request
event, this is the first entry point where you would run your application logic in this event, it could be compared to the traditional index.php
entry point for an application. When running a HTTP server, you don't get access to the Connect
or Receive
events, instead you must use Request
but the Swoole HTTP server on
method still acts the same:
Event Information
The on Request
event provides you with two objects which allow you to interact with the server request and response.
The Swoole HTTP server by default will run using HTTP v1.1 but does support HTTP v2 thanks to the nghttp2
library. Open SSL is required for the HTTP2 protocol to work and Open SSL to support TLS1.2, ALPN and NPN.
When installing Swoole, you need to enable HTTP2 when compiling the PHP extension:
./configure --enable-openssl --enable-http2
At the PHP level, to enable HTTP2 there are a few configuration options and code changes to make. You must enable TCP sockets, Swoole SSL and set the server to use the HTTP2 Protocol.
<?php
// Enable TCP Sockets and SSL
$server = new Swoole\HTTP\Server("127.0.0.1", 9501, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);
// Setup the location of SSL cert and key files
$server->set([
// Setup SSL files
'ssl_cert_file' => $ssl_dir . '/ssl.crt',
'ssl_key_file' => $ssl_dir . '/ssl.key',
// Enable HTTP2 protocol
'open_http2_protocol' => true,
]);
Compared with PHP-FPM or Apache mod_php
, the default Golang HTTP server and the default Node.js HTTP server. The Swoole HTTP server performs much better, Swoole achieves because it takes advantage of multiple processes and utilises the power of coroutines to reach high concurrency, wasting no time or CPU cycles when switching coroutines on worker processes. Swoole runs more efficiently as it has a multi-threaded process model, supports both synchronous and asynchronous code and allows you to write stateful applications. A Swoole server has great performance handling both dynamic applications and static file responses, it is a server that you can run directly from PHP, giving you lots of new high performance features like coroutines and server tasks.
The performance test is done with the Apache benchmark tool, on a normal PC with an Intel Core-I5 which has 4 cores and 8GB memory. This hardware can run a Swoole HTTP server which hits nearly 110K request per second.
Test it out for yourself using our code example
ab -c 200 -n 200000 -k http://127.0.0.1:9501/
There are more server benchmark examples to see.
Even though Swoole is a production ready solution for running a HTTP server directly on your network, you may require some additional features which Swoole does not offer, such as domain routing, load balancing or advanced HTTP configuration, this is why it is sometimes recommend to run your Swoole application behind Nginx using a proxy pass through. Nginx is a tried and testing HTTP server with many ways to configure it, it is not needed but can be useful when paired with Swoole.
A quick start example to use a proxy pass through with Swoole and Nginx:
map $http_upgrade $connection_upgrade
{
default upgrade;
'' close;
}
server
{
listen 80;
server_name your.domain.com;
root /path/to/application/public;
index index.php;
# Enable if any php files must not be accessed
#location ~* \.php$
#{
# return 404;
#}
location /
{
try_files $uri $uri/ @swoole;
}
location @swoole
{
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Enable if using HTTPS/SSL
# proxy_set_header HTTPS "on";
if (!-e $request_filename)
{
proxy_pass http://127.0.0.1:9501;
}
}
}