-
-
Save nilportugues/a6c1c7ccde7fa840925a to your computer and use it in GitHub Desktop.
<?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(); |
When you say lumen in the results do you mean apache/nginx + php running lumen?
@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
@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
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).
@AndrewCarterUK great stuff there. Why don't you add this script to your project? :)
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