Skip to content

Instantly share code, notes, and snippets.

@nilportugues
Last active December 8, 2018 18:33
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nilportugues/a6c1c7ccde7fa840925a to your computer and use it in GitHub Desktop.
Save nilportugues/a6c1c7ccde7fa840925a to your computer and use it in GitHub Desktop.
React+Lumen
<?php
// bootstrap/react.php
// Remember, we need to do first: composer require react/react!
$app = include('app.php');
$host = 'localhost';
$port = 9000;
$reactApp = function (\React\Http\Request $request, \React\Http\Response $response) use ($app, $host, $port) {
$mapRequest = function(\React\Http\Request $request, $content)
{
$method = $request->getMethod();
$headers = $request->getHeaders();
$post = array();
if (isset($headers['Content-Type']) && (0 === strpos($headers['Content-Type'], 'application/x-www-form-urlencoded'))
&& in_array(strtoupper($method), array('POST', 'PUT', 'DELETE', 'PATCH'))
) {
parse_str($content, $post);
}
$sf2Request = new Illuminate\Http\Request($request->getQuery(), $post, array(), array(), array(), array(), $content);
$sf2Request->setMethod($method);
$sf2Request->headers->replace($headers);
$sf2Request->server->set('REQUEST_URI', $request->getPath());
$sf2Request->server->set('SERVER_NAME', explode(':', $headers['Host'])[0]);
return $sf2Request;
};
$mapResponse = function (React\Http\Response $response, Symfony\Component\HttpFoundation\Response $sf2Response)
{
$headers = $sf2Response->headers->all();
$response->writeHead($sf2Response->getStatusCode(), $headers);
if ($sf2Response instanceof Symfony\Component\HttpFoundation\StreamedResponse) {
ob_start();
$sf2Response->sendContent();
$content = ob_get_contents();
ob_end_clean();
}
else {
$content = $sf2Response->getContent();
}
$response->end($content);
};
$mapResponse($response, $app->dispatch($mapRequest($request, null)));
};
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$http = new React\Http\Server($socket);
$http->on('request', $reactApp);
$socket->listen($port);
$loop->run();
@nilportugues
Copy link
Author

Apache AB tool results: ab -n 10000 http://localhost:9000/

React+Lumen

Time per request: 6.510 ms/mean
Requests per second: 153.62

Lumen

Time per request: 11.831 ms/mean
Requests per second: 84.52

@mrsimonbennett
Copy link

When you say lumen in the results do you mean apache/nginx + php running lumen?

@nilportugues
Copy link
Author

@mrsimonbennett I did not use apache or nginx. The server was lauched using the following commands:

##Lumen
php artisan serve

##React+Lumen
php bootstrap/react.php

@nilportugues
Copy link
Author

@mrsimonbennett this method has been already proven to run faster with apache or nginx too, just FYI, check out: https://github.com/php-pm/php-pm

@AndrewCarterUK
Copy link

@nilopc

Nice work, you might be interested in a project I've been working on recently: https://github.com/PHPFastCGI/FastCGIDaemon

Rather than try and replace the webserver, this package allows applications to run as FastCGI applications. That way they can retain the protection of a battle tested webserver and still keep the benefits of staying alive between requests.

I've built adapters for Symfony (http://github.com/PHPFastCGI/SpeedfonyBundle), Silex (http://github.com/PHPFastCGI/Speedex) and Slim (v3) (http://github.com/PHPFastCGI/Slimmer). I was building one for Lumen, however I'm likely going to wait for the next release as there is a method on the App class that (in my opinion) has the wrong visibility set (should be protected) and could cause problems when doing this sort of thing!

The other advantage to this approach is you can actually use apache mod_fastcgi to process manage the workers (although it's only a little bit more work getting it set up with nginx and supervisord).

@nilportugues
Copy link
Author

@AndrewCarterUK great stuff there. Why don't you add this script to your project? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment