Join 4,000+ others and never miss out on new tips, tutorials, and more.
Latest version:
pecl install openswoole-22.1.2 | composer require openswoole/core:22.1.5
The OpenSwoole\HTTP\Server
class inherits from the class OpenSwoole\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 OpenSwoole\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 OpenSwoole, 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(OpenSwoole\Server\Request $request, OpenSwoole\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 OpenSwoole HTTP Server Working Example for the full code.
OpenSwoole\HTTP\Server::__construct
OpenSwoole\HTTP\Server->set
OpenSwoole\HTTP\Server->on
OpenSwoole\HTTP\Server->listen
OpenSwoole\HTTP\Server->addListener
OpenSwoole\HTTP\Server->addProcess
OpenSwoole\Server->addTimer
OpenSwoole\HTTP\Server->start
OpenSwoole\HTTP\Server->reload
OpenSwoole\HTTP\Server->stop
OpenSwoole\HTTP\Server->shutdown
OpenSwoole\HTTP\Server->tick
OpenSwoole\HTTP\Server->after
OpenSwoole\HTTP\Server->defer
OpenSwoole\Server->clearTimer
OpenSwoole\HTTP\Server->close
OpenSwoole\HTTP\Server->send
OpenSwoole\HTTP\Server->sendfile
OpenSwoole\HTTP\Server->sendto
OpenSwoole\HTTP\Server->sendwait
OpenSwoole\HTTP\Server->sendMessage
OpenSwoole\HTTP\Server->exist
OpenSwoole\HTTP\Server->pause
OpenSwoole\HTTP\Server->resume
OpenSwoole\Server->getCallback
OpenSwoole\HTTP\Server->getClientInfo
OpenSwoole\HTTP\Server->getClientList
OpenSwoole\HTTP\Server->bind
OpenSwoole\HTTP\Server->stats
OpenSwoole\Server->task
OpenSwoole\Server->taskWait
OpenSwoole\Server->taskWaitMulti
OpenSwoole\Server->taskCo
OpenSwoole\HTTP\Server->finish
OpenSwoole\HTTP\Server->heartbeat
OpenSwoole\HTTP\Server->getLastError
OpenSwoole\HTTP\Server->getSocket
OpenSwoole\HTTP\Server->protect
OpenSwoole\Server->confirm
OpenSwoole\Server->getReceivedTime
OpenSwoole\Server->getWorkerId
OpenSwoole\Server->getWorkerPid
OpenSwoole\Server->getWorkerStatus
OpenSwoole\Server->getManagerPid
OpenSwoole\Server->getMasterPid
Server Reaction Events
OpenSwoole\Server->on('Start', fn)
OpenSwoole\Server->on('Shutdown', fn)
OpenSwoole\Server->on('WorkerStart', fn)
OpenSwoole\Server->on('WorkerStop', fn)
OpenSwoole\Server->on('WorkerExit', fn)
OpenSwoole\Server->on('Packet', fn)
OpenSwoole\Server->on('Close', fn)
OpenSwoole\Server->on('Task', fn)
OpenSwoole\Server->on('Finish', fn)
OpenSwoole\Server->on('Timer', fn)
OpenSwoole\Server->on('PipeMessage', fn)
OpenSwoole\Server->on('WorkerError', fn)
OpenSwoole\Server->on('ManagerStart', fn)
OpenSwoole\Server->on('ManagerStop', fn)
OpenSwoole\Server->on('BeforeReload', fn)
OpenSwoole\Server->on('AfterReload', fn)
Main HTTP Server Event
Running a HTTP server compared to the normal OpenSwoole 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 OpenSwoole 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 OpenSwoole 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 OpenSwoole, 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, OpenSwoole SSL and set the server to use the HTTP2 Protocol.
<?php
// Enable TCP Sockets and SSL
$server = new OpenSwoole\HTTP\Server("127.0.0.1", 9501, OpenSwoole\Server::POOL_MODE, OpenSwoole\Constant::SOCK_TCP | OpenSwoole\Constant::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 OpenSwoole HTTP server performs much better, OpenSwoole 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. OpenSwoole 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 OpenSwoole 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 OpenSwoole 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 OpenSwoole is a production ready solution for running a HTTP server directly on your network, you may require some additional features which OpenSwoole does not offer, such as domain routing, load balancing or advanced HTTP configuration, this is why it is sometimes recommend to run your OpenSwoole 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 OpenSwoole.
A quick start example to use a proxy pass through with OpenSwoole 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/ @openswoole;
}
location @openswoole
{
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;
}
}
}