Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
asynchronous
steve rhoades twitter+github @steverhoades
Asynchronous PHP
page scraper 
$urls = ['www.amazon.com', ...]; 
! 
foreach($urls as $url) { 
$content = file_get_contents( 
"http://$url",...
request time 
www.amazon.com: 0.80137 
www.reddit.com: 0.21584 
www.hackernews.com: 1.80921 
www.google.com: 0.29365 
www....
time 
call 2 
Network 
call 1 
Network 
call 3 
Network 
blocking i/o
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 mem...
page scraper 
var urls = ['http://www.amazon.com', ...]; 
! 
for(var i in urls) { 
http.get(urls[i], function(response) { ...
request time 
www.amazon.com: 0.75559 
www.reddit.com: 0.33153 
www.hackernews.com: 0.57661 
www.google.com: 0.48226 
www....
call 1 call 2 call 3 
create 
create 
non-blocking i/o 
create 
time 
resp 
resp 
resp 
req 
req 
req
non-blocking i/o 
$urls = ['www.amazon.com',...]; 
! 
foreach($urls as $ip => $url) { 
// create a stream that returns imm...
non-blocking i/o 
while(!empty($sockets)) { //run loop 
$read = $sockets; 
$write = $requests; 
$except = NULL; 
! 
// che...
non-blocking i/o 
www.reddit.com: 0.18858 
www.hackernews.com: 0.37317 
www.google.com: 0.10562 
www.yahoo.com: 0.10172 
w...
event-driven 
non-blocking i/o 
Igor Wiedler 
Christopher Boden 
#reactphp
igorw/evenement EventEmitter 
emit($event, array $arguments = []) 
$this->emit('data', array($data, $this)); 
on($event, c...
service request 
event loop 
dispatcher 
tick 
nextTick 
futureTick 
timers & streams 
demultiplexer 
event handler 
callb...
event loop 
interval 
in seconds 
callback 
Timer object 
timers 
one off timers 
$loop->addTimer(1, function($timer) { 
e...
STREAMS 
Stream($stream, $loop) events: 
data, close, error, drain 
$readStream = new Stream(fopen($file,"r"),$loop); 
$re...
$readStream->pipe($writeStream); 
readableStream 
on->(‘data’) resume() 
writeableStream 
emit->(‘pipe’) 
STREAMS & PIPING...
Promises/A 
states 
“A promise represents the eventual value returned 
from the single completion of an operation.” 
pendi...
working with a Promise 
$loop = ReactEventLoopFactory::create(); 
$factory = new ReactDnsResolverFactory(); 
$dns = $facto...
working with Promiseall() 
$file1 = new file('test_file.txt', "r", $loop); 
$file2 = new file('test_file2.txt', "r", $loop...
SOCKETS 
Server events: 
connection, error 
$loop = ReactEventLoopFactory::create(); 
$socket = new ReactSocketServer($loo...
page scraper 
$factory = new ReactDnsResolverFactory(); 
$dns = $factory->create('8.8.8.8', $loop); 
$urls = ['www.amazon....
request time 
www.reddit.com: 0.47400 
www.hackernews.com: 0.41715 
www.google.com: 0.16216 
www.yahoo.com: 0.15773 
www.a...
Messaging
Messaging Techniques 
polling long polling 
(hanging GET) 
pre-
Messaging Techniques 
long polling 
(hanging GET) 
streaming 
pre-
Server Sent Events 
supported by all major browsers 
var source = new EventSource('stream.php'); 
• automatically re-conne...
demo server sent events
WebSockets 
supported by all major browsers 
• new URI schemes ws and wss 
• bi-directional, full-duplex 
• send messages ...
WebSockets 
supported by all major browsers 
• multiplayer games 
• chat applications 
• social streams 
• auctions
WebSockets API 
supported by all major browsers 
var ws = new WebSocket("ws://www.websockets.org"); 
ws.onopen = function(...
Ratchet 
WebSocket Support for 
• HTTP Server 
• handles WebSockets 
• supports the WAMP 1.0 protocol
Ratchet WebSocket Server 
$socketServer = new ReactSocketServer($loop); 
$socketServer->listen('8080', '0.0.0.0'); 
$webso...
demo web sockets
WAMP 
Web Application Messaging Protocol 
Remote Procedure Calls 
Publish & Subscribe 
autobahn.js
Ratchet 
$socketServer = new ReactSocketServer($loop); 
$socketServer->listen(8080, '0.0.0.0'); 
$wampServer = new IoServe...
Ratchet 
wamp connection 
$conn->callResult($id,$this->playerData); 
$conn->callError($id, $topic, 'You are not allowed to...
demo WAMP
results based on: http://philsturgeon.uk/blog/2013/11/benchmarking-codswallop-nodejs-v-php
OTHER INTERESTING LIBRARIES: 
AMP: dispatch blocking calls to worker threads. 
https://github.com/rdlowrey/Amp 
INTERESTIN...
Q & A 
Code Examples: 
https://github.com/steverhoades/drupalcampla 
http://socketo.me http://reactphp.org
steve rhoades twitter+github @steverhoades
Asynchronous PHP and Real-time Messaging
Upcoming SlideShare
Loading in …5
×

Asynchronous PHP and Real-time Messaging

17,469 views

Published on

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.

Published in: Engineering
  • Hello! High Quality And Affordable Essays For You. Starting at $4.99 per page - Check our website! https://vk.cc/82gJD2
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

×