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 ReactHttpServer(
function(PsrHttpMessageServerRequestInterface $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 ReactHttpMessageResponse(
"200",
array("Access-Control-Allow-Headers" => "*", "Access-Control-Allow-Origin" => "*", "Content-Type" => "application/json"),
json_encode($responseData)
);
}
);
$socketServer = new ReactSocketServer("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?
2
Answers
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
ReactPHP uses an EventLoop and works on single threaded PHP. This means that by calling
sleep()
in your code you block the main thread, therefore the EventLoop is blocked and ReactPHP and the PHP process won’t do anything for the time sleeping. Instead of usingsleep()
you need to set a timer on the event loop.Here is your example script rewritten:
You can find more docs and examples on this topic in the official documentation of the
react/http
library and this specific bit at: https://github.com/reactphp/http#deferred-response.Hope this helps!