OpenSwoole HTTP Server

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

Quick Start

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.

Create a HTTP Server

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);

Setup Server Configuration

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
]);

Register Event Callbacks

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

Start the HTTP Server

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.

Methods

Events

Server Reaction Events

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

Classes

The on Request event provides you with two objects which allow you to interact with the server request and response.

Configuration

HTTP2 Protocol Support

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

OpenSwoole HTTP Server configuration:

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,
]);

HTTP Server Performance

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.

Server Performance Example

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.

Nginx with OpenSwoole Configuration

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;
        }
    }
}
Last updated on September 20, 2022