Successfully reported this slideshow.
Your SlideShare is downloading. ×

Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 16 Ad
Advertisement

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement

Similar to Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze) (20)

More from Péhápkaři (20)

Advertisement

Recently uploaded (20)

Jakub Kulhán - ReactPHP + Symfony = PROFIT (1. sraz přátel Symfony v Praze)

  1. 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. 2. O mně • Kouzelná Almara • Skrz.cz • @jakubkulhan • jakub.kulhan@gmail.com • github.com/jakubkulhan
  3. 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
  4. 4. ReactPHP (neplést s ReactJS!) http://reactphp.org/ (https://github.com/jakubkulhan/hit-server-bench)
  5. 5. ReactPHP: req, res → λ Symfony: req → λ → res ❓
  6. 6. req → λ → promise[res] ❗
  7. 7. github.com/jakubkulhan/ reactphp-symfony
  8. 8. 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();
  9. 9. 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); }
  10. 10. 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(); }
  11. 11. 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()); }
  12. 12. 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(); } }
  13. 13. 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
  14. 14. Díky! Otázky?

×