Search code examples
phphttpserverreactphp

ReactPHP HTTP Server Running Async


I was wondering if there is a way to have a ReactPHP HTTP Server handle requests Asynchronously. I set up a very basic HTTP Server using the documentation (https://github.com/reactphp/http)

HTTPServer.php

<?php

$httpServer = new React\Http\Server(
    function(Psr\Http\Message\ServerRequestInterface $request) {
        $responseData = $request->getUri()->getPath();
        if($responseData == "/testSlow") {sleep(5);} // simulate a slow response time
        if($responseData == "/testFast") {sleep(1);} // simulate a fast response time
        return new React\Http\Message\Response(
            "200",
            array("Access-Control-Allow-Headers" => "*", "Access-Control-Allow-Origin" => "*", "Content-Type" => "application/json"),
            json_encode($responseData)
        );
    }
);

$socketServer = new React\Socket\Server("0.0.0.0:31");
$httpServer->listen($socketServer);

?>

It seems to working fine but Synchronously, if I send a request to the /testSlow path and then immediately to the /testFast path, the slow one will always finish first after 5 seconds and only once it has finished will the fast one then start and finish after 1 second

Am I missing some additional setup?


Solution

  • ReactPHP's event loop handles requests asynchronously, not in parallel. It means that there is only one running process. And call to sleep() hangs this process, i.e. prevents event loop from handling next requests. So, in asynchronous apps (in Node.js as well) it is a common practice to move heavy processing to dedicated processes.

    I am not ReactPHP expert, so cannot provide a working example, but can point the root cause of the problem. I would recommend to read this awesome blog: https://sergeyzhuk.me/reactphp-series, and this article in particular: https://sergeyzhuk.me/2018/05/04/reactphp-child-processes