Weitere ähnliche Inhalte Ähnlich wie Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze) (20) Kürzlich hochgeladen (20) Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)1. ReactPHP + Symfony = PROFIT
aneb 1000req/s s minimálními nároky na server
1. sraz přátel Symfony v Praze (29.10.2015)
2. O mně
• Kouzelná Almara
• Skrz.cz
• @jakubkulhan
• jakub.kulhan@gmail.com
• github.com/jakubkulhan
3. Slovníček
• klik = najedu myší na nabídku a zmáčknu tlačítko
• imprese = podíval jsem se na nabídku
(alespoň polovina nabídky byla ve viewportu
alespoň jednu sekundu)
• CTR (click-through rate) = kliky / imprese
10. Boot
$kernel = new AppKernel(
$environment = $input->getOption("environment"),
$environment !== "prod"
);
$kernel->boot();
$loop = Factory::create();
/** @var Container $container */
$container = $kernel->getContainer();
$container->set("react.loop", $loop);
$socket = new Socket($loop);
$http = new Server($socket);
$http->on("request", function (
Request $request,
Response $response
) use ($kernel, $loop) {
// ...
});
$socket->listen(
$port = $input->getOption("port"),
$host = $input->getOption("host")
);
echo "Listening to {$host}:{$port}n";
$loop->run();
11. ReactPHP → Symfony
$headers = $request->getHeaders();
$cookies = [];
if (isset($headers["Cookie"])) {
foreach ((array)$headers["Cookie"] as $cookieHeader) {
foreach (explode(";", $cookieHeader) as $cookie) {
list($name, $value) = explode("=", trim($cookie), 2);
$cookies[$name] = urldecode($value);
}
}
}
$symfonyRequest = new SymfonyRequest(
$request->getQuery(),
[], // TODO: handle post data
[],
$cookies,
[],
[
"REQUEST_URI" => $request->getPath(),
"SERVER_NAME" => explode(":", $headers["Host"])[0],
"REMOTE_ADDR" => $request->remoteAddress,
"QUERY_STRING" => http_build_query($request->getQuery()),
],
null // TODO: handle post data
);
$symfonyRequest->headers->replace($headers);
$symfonyResponse = $kernel->handle($symfonyRequest);
if ($kernel instanceof TerminableInterface) {
$kernel->terminate($symfonyRequest, $symfonyResponse);
}
12. Symfony → ReactPHP
if ($symfonyResponse instanceof PromiseInterface) {
$symfonyResponse->then(function (SymfonyResponse $symfonyResponse) use ($response) {
$this->send($response, $symfonyResponse);
}, function ($error) use ($loop, $response) {
echo "Exception: ", (string) $error, "n";
$response->writeHead(500, ["Content-Type" => "text/plain"]);
$response->end("500 Internal Server Error");
$loop->stop();
});
} elseif ($symfonyResponse instanceof SymfonyResponse) {
$this->send($response, $symfonyResponse);
} else {
echo "Unsupported response type: ", get_class($symfonyResponse), "n";
$response->writeHead(500, ["Content-Type" => "text/plain"]);
$response->end("500 Internal Server Error");
$loop->stop();
}
13. Symfony → ReactPHP (2)
private function send(Response $res, SymfonyResponse $symfonyResponse)
{
$headers = $symfonyResponse->headers->allPreserveCase();
$headers["X-Powered-By"] = "Love";
$cookies = $symfonyResponse->headers->getCookies();
if (count($cookies)) {
$headers["Set-Cookie"] = [];
foreach ($symfonyResponse->headers->getCookies() as $cookie) {
$headers["Set-Cookie"][] = (string)$cookie;
}
}
$res->writeHead($symfonyResponse->getStatusCode(), $headers);
$res->end($symfonyResponse->getContent());
}
14. Controller
/**
* @Controller
*/
class IndexController
{
/**
* @var LoopInterface
*
* @Autowired
*/
public $loop;
public function indexAction(Request $request)
{
return Response::create("Hello, world!n");
}
public function promiseAction(Request $request)
{
$secs = intval($request->attributes->get("secs"));
$deferred = new Deferred();
$this->loop->addTimer($secs, function () use ($secs, $deferred) {
$deferred->resolve(Response::create("{$secs} seconds later...n"));
});
return $deferred->promise();
}
}
15. Knihovny
• ReactPHP (např. HTTP klient, ZeroMQ)
https://github.com/reactphp
• MySQL
https://github.com/kaja47/async-mysql
https://github.com/KhristenkoYura/react-mysql
https://github.com/bixuehujin/reactphp-mysql
• Redis
https://github.com/nrk/predis-async
• RabbitMQ
https://github.com/jakubkulhan/bunny