Successfully reported this slideshow.
Your SlideShare is downloading. ×

Asynchronous PHP and Real-time Messaging

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Socket programming with php
Socket programming with php
Loading in …3
×

Check these out next

1 of 45 Ad

Asynchronous PHP and Real-time Messaging

Download to read offline

With every major browser supporting WebSockets, HTML 5 has changed how we handle client to server communications. The high demand for real time client and server messaging has developers flocking away from PHP to languages such as Node.js. In this session we'll explore the libraries and extensions that make Asynchronous PHP possible and analyze the performance differences with Node.js. In addition we'll identify use cases and walk through examples of how Asynchronous PHP can handle everything from WebSockets and Message Queues to MySQL.

With every major browser supporting WebSockets, HTML 5 has changed how we handle client to server communications. The high demand for real time client and server messaging has developers flocking away from PHP to languages such as Node.js. In this session we'll explore the libraries and extensions that make Asynchronous PHP possible and analyze the performance differences with Node.js. In addition we'll identify use cases and walk through examples of how Asynchronous PHP can handle everything from WebSockets and Message Queues to MySQL.

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to Asynchronous PHP and Real-time Messaging (20)

Advertisement

Recently uploaded (20)

Asynchronous PHP and Real-time Messaging

  1. 1. asynchronous
  2. 2. steve rhoades twitter+github @steverhoades
  3. 3. Asynchronous PHP
  4. 4. page scraper $urls = ['www.amazon.com', ...]; ! foreach($urls as $url) { $content = file_get_contents( "http://$url", false, $context ); }
  5. 5. request time www.amazon.com: 0.80137 www.reddit.com: 0.21584 www.hackernews.com: 1.80921 www.google.com: 0.29365 www.yahoo.com: 1.39217 ! Total time in seconds: 4.51274
  6. 6. time call 2 Network call 1 Network call 3 Network blocking i/o
  7. 7. I/O is slow. Send 1K bytes over Gbps network 0.01 ms Read 4K randomly from SSD* 0.15 ms Read 1 MB sequentially from memory 0.25 ms Round trip within same datacenter 0.5 ms Read 1 MB sequentially from SSD* 1 ms Disk seek 10 ms Read 1MB sequentially from disk 20 ms Send packet CA->Netherlands->CA 150 ms * Assuming ~1GB/sec SSD source: https://gist.github.com/jboner/2841832
  8. 8. page scraper var urls = ['http://www.amazon.com', ...]; ! for(var i in urls) { http.get(urls[i], function(response) { var str = ''; response.on('data', function (chunk) { str += chunk; }); ! response.on('end', function () { // do something with data }); }); }
  9. 9. request time www.amazon.com: 0.75559 www.reddit.com: 0.33153 www.hackernews.com: 0.57661 www.google.com: 0.48226 www.yahoo.com: 0.23333 ! Total time: 0.76421
  10. 10. call 1 call 2 call 3 create create non-blocking i/o create time resp resp resp req req req
  11. 11. non-blocking i/o $urls = ['www.amazon.com',...]; ! foreach($urls as $ip => $url) { // create a stream that returns immediately // STREAM_CLIENT_CONNECT _MUST_ be passed // STREAM_CLIENT_ASYNC_CONNECT says create connection // asynchronously $socket = stream_socket_client( "tcp://$ip:80", $errno, $errstr, 0, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT ); // set stream as non-blocking with 0, default is 1 stream_set_blocking($socket, 0); ! // sockets = read streams, requests = write streams $sockets[(int) $socket] = $socket; $requests[(int) $socket] = $socket; }
  12. 12. non-blocking i/o while(!empty($sockets)) { //run loop $read = $sockets; $write = $requests; $except = NULL; ! // check the multiplexer for stream events $ready = stream_select($read, $write, $except, 0); foreach($read as $readFd) { // .. read } foreach($write as $writeFd) { // .. write } }
  13. 13. non-blocking i/o www.reddit.com: 0.18858 www.hackernews.com: 0.37317 www.google.com: 0.10562 www.yahoo.com: 0.10172 www.amazon.com: 0.68584 ! Total time: 0.69041 (PHP Blocking Example: 4.51274)
  14. 14. event-driven non-blocking i/o Igor Wiedler Christopher Boden #reactphp
  15. 15. igorw/evenement EventEmitter emit($event, array $arguments = []) $this->emit('data', array($data, $this)); on($event, callable $listener) $this->on('pipe', array($this, 'handleEvent')); once($event, callable $listener) $this->once('init', array($this, 'configure'));
  16. 16. service request event loop dispatcher tick nextTick futureTick timers & streams demultiplexer event handler callback
  17. 17. event loop interval in seconds callback Timer object timers one off timers $loop->addTimer(1, function($timer) { echo "I'm a one off timer.” . PHP_EOL; }); periodic timers $loop->addPeriodicTimer(1, function($timer) { echo "Yes, I am annoying =)" . PHP_EOL; }); // cancel that annoying timer ! $timer->cancel(); });
  18. 18. STREAMS Stream($stream, $loop) events: data, close, error, drain $readStream = new Stream(fopen($file,"r"),$loop); $readStream->on('data',function($data, $stream) { //do something with $data });
  19. 19. $readStream->pipe($writeStream); readableStream on->(‘data’) resume() writeableStream emit->(‘pipe’) STREAMS & PIPING on->(‘drain’) write($data) end() end() pause() if $data > $limit
  20. 20. Promises/A states “A promise represents the eventual value returned from the single completion of an operation.” pending, fulfilled, rejected “once fulfilled or rejected the promise’s value shall not be changed” http://wiki.commonjs.org/wiki/Promises/A
  21. 21. working with a Promise $loop = ReactEventLoopFactory::create(); $factory = new ReactDnsResolverFactory(); $dns = $factory->create('8.8.8.8', $loop); ! $dns ->resolve('github.com') ->then(function ($ip) { echo "Host: $ipn"; } ); $loop->run(); Deferred
  22. 22. working with Promiseall() $file1 = new file('test_file.txt', "r", $loop); $file2 = new file('test_file2.txt', "r", $loop); $promises = array( $file1->read(), $file2->read() ); ! Promiseall($promises)->then(function($v){}); Promiserace($promises)->then(function($v){}); Promisesome($promises, 4)->then(function($v){});
  23. 23. SOCKETS Server events: connection, error $loop = ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); ! $socket->on('connection', function($conn) { echo $conn->getRemoteAddress() . " connected" . PHP_EOL; $conn->on('data', function($data) { echo "Data received for connection" . PHP_EOL; Connection extends Stream events: data, close, error, drain }); }); ! $socket->listen(4000); $loop->run();
  24. 24. page scraper $factory = new ReactDnsResolverFactory(); $dns = $factory->create('8.8.8.8', $loop); $urls = ['www.amazon.com',...]; $msg = "GET / HTTP/1.0rnAccept: */*rnrn"; ! foreach($urls as $url) { $connector = new ReactSocketClientConnector($loop, $dns); $connector->create($url, 80)->then( function (ReactStreamStream $stream) use ($msg){ $stream->write($msg); $stream->on('data', function($data, $stream) { // buffer data } ); $stream->on('end', function($stream) { // do something with the data $stream->close(); }); } ); } $loop->run();
  25. 25. request time www.reddit.com: 0.47400 www.hackernews.com: 0.41715 www.google.com: 0.16216 www.yahoo.com: 0.15773 www.amazon.com: 0.65287 ! Total time: 0.69455 (PHP Blocking Example: 4.51274)
  26. 26. Messaging
  27. 27. Messaging Techniques polling long polling (hanging GET) pre-
  28. 28. Messaging Techniques long polling (hanging GET) streaming pre-
  29. 29. Server Sent Events supported by all major browsers var source = new EventSource('stream.php'); • automatically re-connects • uni-directional • send arbitrary events source.addEventListener('message', function(e) { console.log(e.data); }, false);
  30. 30. demo server sent events
  31. 31. WebSockets supported by all major browsers • new URI schemes ws and wss • bi-directional, full-duplex • send messages independently
  32. 32. WebSockets supported by all major browsers • multiplayer games • chat applications • social streams • auctions
  33. 33. WebSockets API supported by all major browsers var ws = new WebSocket("ws://www.websockets.org"); ws.onopen = function(e) { console.log("Connection open ..."); }; ws.onmessage = function(e) { console.log( "Received Message: " + e.data); }; ws.onclose = function(e) { console.log("Connection closed."); }; ws.send("Hello WebSockets!"); ws.close();
  34. 34. Ratchet WebSocket Support for • HTTP Server • handles WebSockets • supports the WAMP 1.0 protocol
  35. 35. Ratchet WebSocket Server $socketServer = new ReactSocketServer($loop); $socketServer->listen('8080', '0.0.0.0'); $websocketServer = new IoServer( new HttpServer( new WsServer( $myWsApp ) ), $socketServer, $loop ); onOpen($conn) onClose($conn) onError($from, $error) onMessage($from, $msg)
  36. 36. demo web sockets
  37. 37. WAMP Web Application Messaging Protocol Remote Procedure Calls Publish & Subscribe autobahn.js
  38. 38. Ratchet $socketServer = new ReactSocketServer($loop); $socketServer->listen(8080, '0.0.0.0'); $wampServer = new IoServer( new HttpServer( new WsServer( new WampServer( $myWampApp ) ) ), $socketServer, $loop ); onCall($conn, $id, $topic, $params) onPublish($conn, $topic, $event) onSubscribe($conn, $topic) onUnsubscribe($conn, $topic)
  39. 39. Ratchet wamp connection $conn->callResult($id,$this->playerData); $conn->callError($id, $topic, 'You are not allowed to make calls'); topic $topic->broadcast($event, array($conn->WAMP->sessionId));
  40. 40. demo WAMP
  41. 41. results based on: http://philsturgeon.uk/blog/2013/11/benchmarking-codswallop-nodejs-v-php
  42. 42. OTHER INTERESTING LIBRARIES: AMP: dispatch blocking calls to worker threads. https://github.com/rdlowrey/Amp INTERESTING READS: COOPERATIVE MULTI-TASKING USING COROUTINES IN PHP http://bit.ly/1nTAV4e - nikic
  43. 43. Q & A Code Examples: https://github.com/steverhoades/drupalcampla http://socketo.me http://reactphp.org
  44. 44. steve rhoades twitter+github @steverhoades

×