0
Realtime Communication Techniques with PHP Scott Mattocks & Chris Lewis, OnForce, Inc.
Agenda <ul><li>Introductions </li></ul><ul><li>Overview </li></ul><ul><ul><li>User expectations </li></ul></ul><ul><ul><li...
Introductions <ul><li>Scott Mattocks </li></ul><ul><ul><li>Senior PHP developer at OnForce, Inc. </li></ul></ul><ul><ul><l...
Overview <ul><li>Example:  http://www.spoutserver.com </li></ul><ul><ul><li>Click “John Locke” in the Demos section </li><...
Overview <ul><li>Users expect data to be delivered more quickly and seemlessly </li></ul><ul><ul><li>Gmail changed the way...
Problems with delivery <ul><li>The web runs (for the most part) on HTTP </li></ul><ul><ul><li>HTTP is one way </li></ul></...
Problems with delivery <ul><li>Timeliness </li></ul><ul><ul><li>There is a gap between arrival of the data on the server a...
Problems with delivery <ul><li>Efficiency </li></ul><ul><ul><li>How much of the transfered data is important to the user? ...
Problems with delivery <ul><li>Scalability </li></ul><ul><ul><li>What kind of load are we causing on the server? </li></ul...
Solutions <ul><li>Refresh the page </li></ul><ul><li>Short Polling </li></ul><ul><li>Long Polling </li></ul><ul><ul><li>1 ...
Solutions @gnomeboy want to come over for some cookies? @gnomegirl hellz yeah! <ul><li>Example: Simple twitter feed style ...
Solutions <ul><li>Page consists of a wrapper around message content </li></ul><ul><ul><li>Avg message size = 100 bytes </l...
Refresh <ul><li>The same as if the user hit  F5 </li></ul><ul><ul><li>Reloads the entire page </li></ul></ul><ul><ul><li>N...
Refresh database web server web server
Refresh <ul><li>Difficulty </li></ul><ul><ul><li>1 out of 10 </li></ul></ul><ul><ul><li>Use HTML or JavaScript </li></ul><...
Refresh <ul><li>Timeliness </li></ul><ul><ul><li>Timeliness of data depends on the refresh rate </li></ul></ul><ul><ul><li...
Refresh <ul><li>Efficiency (assume 10 total requests, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul><...
Short Polling <ul><li>Ask the server for updates since the last time you asked </li></ul><ul><ul><li>Like a road trip with...
Short Polling database web server web server
Short Polling <ul><li>Difficulty </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJAX </li></ul></ul><ul><ul>...
Short Polling function   poll_server () { new  Ajax. Request ( this .urlPolling, { method:  'post' , parameters: data, onS...
Short Polling function   successHandler (trans, messages_div) { if  (trans.responseText) { var  json = trans.responseText....
Short Polling function   successHandler (trans, messages_div) { if  (trans.responseText) { var  json = trans.responseText....
Short Polling <ul><li>Timeliness </li></ul><ul><ul><li>Timeliness of data depends on the refresh rate </li></ul></ul><ul><...
Short Polling <ul><li>Efficiency (assume 10 total requests, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul>...
Long Polling - 1 server <ul><li>Ask the server for updates since the last time you asked </li></ul><ul><ul><li>Server does...
Long Polling – 1 server database web server web server
Long Polling – 1 server <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJAX...
Long Polling – 1 server <ul><li>Difficulty – Server side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>Cont...
Long Polling – 1 server function   poll_server () { new  Ajax. Request ( this .urlPolling, { method:  'post' , parameters:...
Long Polling – 1 server function   successHandler (trans, messages_div) { if  (trans.responseText) { var  json = trans.res...
Long Polling – 1 server <?php $query  =  'SELECT message FROM messages WHERE dateadded > ?' ; $stmt   =  $pdo -> prepare (...
Long Polling – 1 server <ul><li>Timeliness </li></ul><ul><ul><li>Near real-time </li></ul></ul><ul><ul><li>As soon as a me...
Long Polling – 1 server <ul><li>Efficiency (1 request, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul>...
Long Polling – 2 servers <ul><li>2 servers work together to use fewer resources </li></ul><ul><ul><li>Main web server hand...
Long Polling – 2 servers web server polling server HTTP XHR over HTTP
Long Polling – 2 servers <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJA...
Long Polling – 2 servers <ul><li>Difficulty – Server side </li></ul><ul><ul><li>8 out of 10 </li></ul></ul><ul><ul><li>Web...
Long Polling – 2 servers function   poll_server () { new  Ajax. Request ( this .urlPolling, { method:  'post' , parameters...
Long Polling – 2 servers function   successHandler (trans, messages_div) { if  (trans.responseText) { var  json = trans.re...
Long Polling – 2 servers Main Web Server Polling Server <?php $query  =  'INSERT INTO messages VALUES (?, ?)' ; $stmt   = ...
Long Polling – 2 servers <ul><li>Timeliness </li></ul><ul><ul><li>Near real-time </li></ul></ul><ul><ul><li>As soon as a m...
Long Polling – 2 servers <ul><li>Efficiency (1 request, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul...
WebSockets <ul><li>According to http://en.wikipedia.org/wiki/WebSocket: </li></ul><ul><li>„ WebSockets is a technology pro...
WebSockets <ul><li>WebSockets allow server to push data to client </li></ul><ul><li>Connection established via client-init...
WebSockets <ul><li>Builds off of 2 server long polling </li></ul><ul><ul><li>Main web server communicates with event serve...
WebSockets web server WebSocket server JSON via WebSockets
WebSockets <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>WebSocket API </l...
WebSockets <ul><li>Difficulty – Server side </li></ul><ul><ul><li>8 out of 10 </li></ul></ul><ul><ul><li>Web server makes ...
WebSockets function   poll_server () { var  socket =  new   WebSocket ( 'ws://example.com/' ); socket.onmessage =  functio...
WebSockets function   successHandler (trans, messages_div) { if  (trans.data) { var  json = trans.data. evalJSON (); if  (...
WebSockets Main Web Server WebSocket Server <?php $query  =  'INSERT INTO messages VALUES (?, ?)' ; $stmt   =  $pdo -> pre...
WebSockets <ul><li>Timeliness </li></ul><ul><ul><li>Real-time </li></ul></ul><ul><ul><li>As soon as a message shows up on ...
WebSockets <ul><li>Post Handshake Efficiency  </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>0 bytes ...
WebSockets <ul><li>Efficiency Demo </li></ul><ul><ul><li>http://spoutserver.com/demos/compare </li></ul></ul><ul><li>Compa...
WaterSpout <ul><li>Lightweight HTTP server </li></ul><ul><ul><li>Static files </li></ul></ul><ul><ul><li>Dynamic content (...
WaterSpout <ul><li>Two types of connections </li></ul><ul><ul><li>Listeners </li></ul></ul><ul><ul><li>Updates </li></ul><...
WaterSpout - Listeners <?php public function   listen () { // Handle cursor for long polling fall back. // ... $this ->dis...
WaterSpout - Dispatcher <?php /* Called every .25 seconds on all waiting listeners */ public function   process_event (Con...
WaterSpout vs Apache/Nginx <ul><li>Neither Apache nor Nginx has a way for one process to notify the listeners </li></ul><u...
WebSockets <ul><li>Resources </li></ul><ul><ul><li>http://dev.w3.org/html5/websockets/ </li></ul></ul><ul><ul><li>http://e...
Questions? <ul><li>Contact </li></ul><ul><ul><li>[email_address] </li></ul></ul><ul><li>Twitter </li></ul><ul><ul><li>@spo...
Upcoming SlideShare
Loading in...5
×

Realtime Communication Techniques with PHP

80,807

Published on

Published in: Technology
1 Comment
19 Likes
Statistics
Notes
  • It seems to be like http://www.spoutserver.com is no longer valid..
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
80,807
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
304
Comments
1
Likes
19
Embeds 0
No embeds

No notes for slide
  • - Once upon a time, the internet was flat. Users asked for content and web servers gave it to them. - XMLHttpRequest came along and change all of that. - Google said “well, we know they are going to ask for their new messages soon anyway, so why not give them the new messages before they ask?”
  • - Unless you are Facebook, the database is your bottle neck. - Solutions that consume database resources are not very scalable - Timeliness is often sacrificed for scalability
  • Basically the same as refresh but with less data transfered
  • Transcript of "Realtime Communication Techniques with PHP"

    1. 1. Realtime Communication Techniques with PHP Scott Mattocks & Chris Lewis, OnForce, Inc.
    2. 2. Agenda <ul><li>Introductions </li></ul><ul><li>Overview </li></ul><ul><ul><li>User expectations </li></ul></ul><ul><ul><li>Problems with delivery </li></ul></ul><ul><li>Techniques </li></ul><ul><ul><li>Refresh </li></ul></ul><ul><ul><li>Short Polling </li></ul></ul><ul><ul><li>Long Polling </li></ul></ul><ul><ul><li>WebSockets </li></ul></ul><ul><li>Q&A </li></ul>
    3. 3. Introductions <ul><li>Scott Mattocks </li></ul><ul><ul><li>Senior PHP developer at OnForce, Inc. </li></ul></ul><ul><ul><li>Contributor to PEAR </li></ul></ul><ul><ul><li>Author of Pro PHP-GTK </li></ul></ul><ul><li>Chris Lewis </li></ul><ul><ul><li>Senior PHP developer at OnForce, Inc. </li></ul></ul><ul><ul><li>6 years of enterprise PHP experience </li></ul></ul><ul><ul><li>12 years of front-end web development experience </li></ul></ul><ul><li>Both are contributors to the WaterSpout Real-time Communication Server </li></ul>
    4. 4. Overview <ul><li>Example: http://www.spoutserver.com </li></ul><ul><ul><li>Click “John Locke” in the Demos section </li></ul></ul>
    5. 5. Overview <ul><li>Users expect data to be delivered more quickly and seemlessly </li></ul><ul><ul><li>Gmail changed the way user expect to interact with websites </li></ul></ul><ul><li>Loading an entire page to show a small change is slow and wasteful </li></ul>
    6. 6. Problems with delivery <ul><li>The web runs (for the most part) on HTTP </li></ul><ul><ul><li>HTTP is one way </li></ul></ul><ul><ul><li>User asks for data </li></ul></ul><ul><ul><li>Server sends data back </li></ul></ul><ul><ul><li>The server can't do anything without the user asking first </li></ul></ul>
    7. 7. Problems with delivery <ul><li>Timeliness </li></ul><ul><ul><li>There is a gap between arrival of the data on the server and notification of the user. </li></ul></ul><ul><ul><li>We want to reduce the gap without killing the servers. </li></ul></ul>Client Server New Data New Data Black out
    8. 8. Problems with delivery <ul><li>Efficiency </li></ul><ul><ul><li>How much of the transfered data is important to the user? </li></ul></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>X bytes sent for request (GET headers) </li></ul></ul></ul><ul><ul><ul><li>Y bytes sent for response (body and headers) </li></ul></ul></ul><ul><ul><ul><li>Z bytes of new data </li></ul></ul></ul><ul><ul><ul><li>Z / (X + Y) = efficiency </li></ul></ul></ul><ul><ul><li>We want try to send only the data that has changed and that is important to the user </li></ul></ul>
    9. 9. Problems with delivery <ul><li>Scalability </li></ul><ul><ul><li>What kind of load are we causing on the server? </li></ul></ul><ul><ul><li>Are we holding resources (i.e. database connections) that could be used to server other users? </li></ul></ul><ul><ul><li>We want to do more with less </li></ul></ul>
    10. 10. Solutions <ul><li>Refresh the page </li></ul><ul><li>Short Polling </li></ul><ul><li>Long Polling </li></ul><ul><ul><li>1 server </li></ul></ul><ul><ul><li>2 servers </li></ul></ul><ul><li>WebSockets </li></ul>
    11. 11. Solutions @gnomeboy want to come over for some cookies? @gnomegirl hellz yeah! <ul><li>Example: Simple twitter feed style page </li></ul>
    12. 12. Solutions <ul><li>Page consists of a wrapper around message content </li></ul><ul><ul><li>Avg message size = 100 bytes </li></ul></ul><ul><ul><li>Avg page size (without images) = 4 KB </li></ul></ul><ul><ul><li>Avg request headers = 410 bytes </li></ul></ul><ul><ul><li>Avg response headers = 210 bytes </li></ul></ul><ul><li>(JavaScript code examples use Prototype) </li></ul>
    13. 13. Refresh <ul><li>The same as if the user hit F5 </li></ul><ul><ul><li>Reloads the entire page </li></ul></ul><ul><ul><li>New page load adds the new message </li></ul></ul><ul><li>No constant connection to the server </li></ul><ul><ul><li>Black out periods between requests </li></ul></ul>
    14. 14. Refresh database web server web server
    15. 15. Refresh <ul><li>Difficulty </li></ul><ul><ul><li>1 out of 10 </li></ul></ul><ul><ul><li>Use HTML or JavaScript </li></ul></ul><ul><li><meta http-equiv=&quot;refresh&quot; content=&quot;5&quot; /> </li></ul><ul><li>setTimeout('window.location.reload(true)', 5000); </li></ul>
    16. 16. Refresh <ul><li>Timeliness </li></ul><ul><ul><li>Timeliness of data depends on the refresh rate </li></ul></ul><ul><ul><li>There is an additional delay for the round trip to the server </li></ul></ul><ul><ul><ul><li>Includes time to send request, process request, and send response </li></ul></ul></ul>
    17. 17. Refresh <ul><li>Efficiency (assume 10 total requests, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>410 bytes sent for each request </li></ul></ul></ul><ul><ul><ul><li>4210 bytes sent for each response, 4310 for new message response </li></ul></ul></ul><ul><ul><ul><li>100 bytes of new data </li></ul></ul></ul><ul><ul><ul><li>100 / ((410 + 4210) * 10 + 100) = .0021 per message </li></ul></ul></ul><ul><ul><li>Server resources used </li></ul></ul><ul><ul><ul><li>1 HTTP process per request (10 total) </li></ul></ul></ul><ul><ul><ul><li>1 Database connection per request (10 total) </li></ul></ul></ul>
    18. 18. Short Polling <ul><li>Ask the server for updates since the last time you asked </li></ul><ul><ul><li>Like a road trip with a 3 year old </li></ul></ul><ul><ul><li>Are we there yet? Are we there yet? </li></ul></ul><ul><li>No constant connection to the server </li></ul><ul><ul><li>Black out periods between requests </li></ul></ul><ul><ul><li>Cursor required to prevent data loss </li></ul></ul>
    19. 19. Short Polling database web server web server
    20. 20. Short Polling <ul><li>Difficulty </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJAX </li></ul></ul><ul><ul><ul><li>Background request to the server checks for new messages at a timed interval </li></ul></ul></ul><ul><ul><ul><li>New messages are added to DOM by JavaScript </li></ul></ul></ul>
    21. 21. Short Polling function poll_server () { new Ajax. Request ( this .urlPolling, { method: 'post' , parameters: data, onSuccess: this .successHandler, onFailure: this .handleFailure, onException: this .handleException }); } setInterval ( 'poll_server()' , 5000 );
    22. 22. Short Polling function successHandler (trans, messages_div) { if (trans.responseText) { var json = trans.responseText. evalJSON (); if (json.message) { var msg = json.message + '<br />' ; $(messages_div). insert (msg); } } }
    23. 23. Short Polling function successHandler (trans, messages_div) { if (trans.responseText) { var json = trans.responseText. evalJSON (); if (json.message) { var msg = json.message + '<br />' ; $(messages_div). insert (msg); } } }
    24. 24. Short Polling <ul><li>Timeliness </li></ul><ul><ul><li>Timeliness of data depends on the refresh rate </li></ul></ul><ul><ul><li>There is an additional delay for the round trip to the server </li></ul></ul><ul><ul><ul><li>Includes time to send request, process request, and send response </li></ul></ul></ul>
    25. 25. Short Polling <ul><li>Efficiency (assume 10 total requests, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>410 bytes sent for each request </li></ul></ul></ul><ul><ul><ul><li>210 bytes sent for each empty response, 310 for new message response </li></ul></ul></ul><ul><ul><ul><li>100 bytes of new data </li></ul></ul></ul><ul><ul><ul><li>100 / ((410 + 210) * 10 + 100) = .0158 per message </li></ul></ul></ul><ul><ul><li>Server resources used </li></ul></ul><ul><ul><ul><li>1 HTTP process per request (10 total) </li></ul></ul></ul><ul><ul><ul><li>1 Database connection per request (10 total) </li></ul></ul></ul>
    26. 26. Long Polling - 1 server <ul><li>Ask the server for updates since the last time you asked </li></ul><ul><ul><li>Server does not respond until a new message has arrived </li></ul></ul><ul><li>No constant connection to the server </li></ul><ul><ul><li>Black out periods between sending response and next request </li></ul></ul><ul><ul><li>Cursor required to prevent data loss </li></ul></ul>
    27. 27. Long Polling – 1 server database web server web server
    28. 28. Long Polling – 1 server <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJAX </li></ul></ul><ul><ul><ul><li>Background request to the server checks for new messages and waits for responses </li></ul></ul></ul><ul><ul><ul><li>New messages are added to DOM by JavaScript </li></ul></ul></ul>
    29. 29. Long Polling – 1 server <ul><li>Difficulty – Server side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>Continuously loop checking for new messages </li></ul></ul><ul><ul><li>Break out of loop when new message arrives </li></ul></ul>
    30. 30. Long Polling – 1 server function poll_server () { new Ajax. Request ( this .urlPolling, { method: 'post' , parameters: data, onSuccess: this .successHandler, onFailure: this .handleFailure, onException: this .handleException }); } document. observe ( 'dom:loaded' , poll_server);
    31. 31. Long Polling – 1 server function successHandler (trans, messages_div) { if (trans.responseText) { var json = trans.responseText. evalJSON (); if (json.message) { var msg = json.message + '<br />' ; $(messages_div). insert (msg); } } poll_server (); }
    32. 32. Long Polling – 1 server <?php $query = 'SELECT message FROM messages WHERE dateadded > ?' ; $stmt = $pdo -> prepare ( $query ); while (true) { $message = $stmt -> execute ( $cursor_date ); if (! empty ( $message )) { echo json_encode ( $message ); break ; } } ?>
    33. 33. Long Polling – 1 server <ul><li>Timeliness </li></ul><ul><ul><li>Near real-time </li></ul></ul><ul><ul><li>As soon as a message shows up on the server, it is sent to the waiting client </li></ul></ul><ul><ul><li>Black out period between sending response and making new request can add some delay </li></ul></ul>
    34. 34. Long Polling – 1 server <ul><li>Efficiency (1 request, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>410 bytes sent for request </li></ul></ul></ul><ul><ul><ul><li>310 bytes for new message response </li></ul></ul></ul><ul><ul><ul><li>100 bytes of new data </li></ul></ul></ul><ul><ul><ul><li>100 / (410 + 310) = .138 per message </li></ul></ul></ul><ul><ul><li>Server resources used </li></ul></ul><ul><ul><ul><li>1 HTTP process </li></ul></ul></ul><ul><ul><ul><li>1 Database connection </li></ul></ul></ul>
    35. 35. Long Polling – 2 servers <ul><li>2 servers work together to use fewer resources </li></ul><ul><ul><li>Main web server handles initial page request </li></ul></ul><ul><ul><li>Main server informs polling server when new message arrives </li></ul></ul><ul><ul><li>Polling server informs client </li></ul></ul><ul><li>No constant connection to server </li></ul><ul><ul><li>Black out periods between sending response and next request </li></ul></ul><ul><ul><li>Cursor required to prevent data loss </li></ul></ul>
    36. 36. Long Polling – 2 servers web server polling server HTTP XHR over HTTP
    37. 37. Long Polling – 2 servers <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>AJAX </li></ul></ul><ul><ul><ul><li>Background request to the server checks for new messages and waits for responses </li></ul></ul></ul><ul><ul><ul><li>New messages are added to DOM by JavaScript </li></ul></ul></ul>
    38. 38. Long Polling – 2 servers <ul><li>Difficulty – Server side </li></ul><ul><ul><li>8 out of 10 </li></ul></ul><ul><ul><li>Web server makes cURL call to polling server when a new message is added </li></ul></ul><ul><ul><li>Polling server determines who message is for and sends the response to the waiting connection </li></ul></ul>
    39. 39. Long Polling – 2 servers function poll_server () { new Ajax. Request ( this .urlPolling, { method: 'post' , parameters: data, onSuccess: this .successHandler, onFailure: this .handleFailure, onException: this .handleException }); } document. observe ( 'dom:loaded' , poll_server);
    40. 40. Long Polling – 2 servers function successHandler (trans, messages_div) { if (trans.responseText) { var json = trans.responseText. evalJSON (); if (json.message) { var msg = json.message + '<br />' ; $(messages_div). insert (msg); } } poll_server (); }
    41. 41. Long Polling – 2 servers Main Web Server Polling Server <?php $query = 'INSERT INTO messages VALUES (?, ?)' ; $stmt = $pdo -> prepare ( $query ); $stmt -> prepare ( $message , $date ); $polling_server -> send ( $message ); ?> <?php foreach ( $this ->waiting as $connection ){ $connection -> respond ( $message ); } ?>
    42. 42. Long Polling – 2 servers <ul><li>Timeliness </li></ul><ul><ul><li>Near real-time </li></ul></ul><ul><ul><li>As soon as a message shows up on the server, it is sent to the waiting client </li></ul></ul><ul><ul><li>Black out period between sending response and making new request can add some delay </li></ul></ul>
    43. 43. Long Polling – 2 servers <ul><li>Efficiency (1 request, 1 new message) </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>410 bytes sent for request </li></ul></ul></ul><ul><ul><ul><li>310 bytes for new message response </li></ul></ul></ul><ul><ul><ul><li>100 bytes of new data </li></ul></ul></ul><ul><ul><ul><li>100 / (410 + 310) = .138 per message </li></ul></ul></ul><ul><ul><li>Server resources used </li></ul></ul><ul><ul><ul><li>1 HTTP process on polling server per message </li></ul></ul></ul><ul><ul><ul><li>0 Database connections </li></ul></ul></ul>
    44. 44. WebSockets <ul><li>According to http://en.wikipedia.org/wiki/WebSocket: </li></ul><ul><li>„ WebSockets is a technology providing for bi-directional, full-duplex communications channels, over a single Transmission Control Protocol (TCP) socket, designed to be implemented in web browsers and web servers” </li></ul>
    45. 45. WebSockets <ul><li>WebSockets allow server to push data to client </li></ul><ul><li>Connection established via client-initiated handshake </li></ul><ul><li>After handshake, both the client and the server can send and recieve data </li></ul><ul><ul><li>Server can send data without the client asking for it first </li></ul></ul>
    46. 46. WebSockets <ul><li>Builds off of 2 server long polling </li></ul><ul><ul><li>Main web server communicates with event server </li></ul></ul><ul><li>Constant connection between client and server </li></ul><ul><ul><li>No black out periods </li></ul></ul><ul><ul><li>No need for cursor </li></ul></ul>
    47. 47. WebSockets web server WebSocket server JSON via WebSockets
    48. 48. WebSockets <ul><li>Difficulty – Client side </li></ul><ul><ul><li>5 out of 10 </li></ul></ul><ul><ul><li>WebSocket API </li></ul></ul><ul><ul><ul><li>Connection established </li></ul></ul></ul><ul><ul><ul><li>onMessage events fired when new data comes in from the server </li></ul></ul></ul><ul><ul><ul><li>New messages are added to DOM by JavaScript </li></ul></ul></ul>
    49. 49. WebSockets <ul><li>Difficulty – Server side </li></ul><ul><ul><li>8 out of 10 </li></ul></ul><ul><ul><li>Web server makes cURL call to WebSocket server when a new message is added </li></ul></ul><ul><ul><li>WebSocket server determines who message is for and sends the response to the waiting connection </li></ul></ul>
    50. 50. WebSockets function poll_server () { var socket = new WebSocket ( 'ws://example.com/' ); socket.onmessage = function (response) { successHandler (response, 'message_errors' ); } } document. observe ( 'dom:loaded' , poll_server);
    51. 51. WebSockets function successHandler (trans, messages_div) { if (trans.data) { var json = trans.data. evalJSON (); if (json.message) { var msg = json.message + '<br />' ; $(messages_div). insert (msg); } } }
    52. 52. WebSockets Main Web Server WebSocket Server <?php $query = 'INSERT INTO messages VALUES (?, ?)' ; $stmt = $pdo -> prepare ( $query ); $stmt -> prepare ( $message , $date ); $polling_server -> send ( $message ); ?> <?php foreach ( $this ->waiting as $connection ){ $connection -> respond ( $message ); } ?>
    53. 53. WebSockets <ul><li>Timeliness </li></ul><ul><ul><li>Real-time </li></ul></ul><ul><ul><li>As soon as a message shows up on the server, it is sent to the waiting client </li></ul></ul><ul><ul><li>No black out period </li></ul></ul>
    54. 54. WebSockets <ul><li>Post Handshake Efficiency </li></ul><ul><ul><li>Data transfer: </li></ul></ul><ul><ul><ul><li>0 bytes sent for request </li></ul></ul></ul><ul><ul><ul><li>100 bytes for new message response </li></ul></ul></ul><ul><ul><ul><li>100 bytes of new data </li></ul></ul></ul><ul><ul><ul><li>100 / 100 = 1.000 per message </li></ul></ul></ul><ul><ul><li>Server resources used </li></ul></ul><ul><ul><ul><li>1 process on WebSocket server </li></ul></ul></ul><ul><ul><ul><li>0 Database connections </li></ul></ul></ul>
    55. 55. WebSockets <ul><li>Efficiency Demo </li></ul><ul><ul><li>http://spoutserver.com/demos/compare </li></ul></ul><ul><li>Comparison </li></ul><ul><ul><li>Refresh: .0021 </li></ul></ul><ul><ul><li>Short Polling: .0158 </li></ul></ul><ul><ul><li>Long Polling: .138 </li></ul></ul><ul><ul><li>WebSockets: 1.00 </li></ul></ul>
    56. 56. WaterSpout <ul><li>Lightweight HTTP server </li></ul><ul><ul><li>Static files </li></ul></ul><ul><ul><li>Dynamic content (PHP) </li></ul></ul><ul><li>Best used as part of event-driven server pair </li></ul><ul><ul><li>Can function as both ends </li></ul></ul><ul><li>Handles WebSockets and long polling </li></ul><ul><li>Written in PHP </li></ul>
    57. 57. WaterSpout <ul><li>Two types of connections </li></ul><ul><ul><li>Listeners </li></ul></ul><ul><ul><li>Updates </li></ul></ul><ul><li>When an update comes in the appropriate listeners are notified </li></ul><ul><ul><li>Custom controllers define which listeners should be notified </li></ul></ul>
    58. 58. WaterSpout - Listeners <?php public function listen () { // Handle cursor for long polling fall back. // ... $this ->dispatcher-> add_listener ( $this ); } ?>
    59. 59. WaterSpout - Dispatcher <?php /* Called every .25 seconds on all waiting listeners */ public function process_event (Controller $mover = null) { $key = array_search (( int ) $this ->_cursor, array_keys (self:: $_commands )); if ( $key === false && ! is_null ( $this ->_cursor)) { return ; } $commands = array_slice (self:: $_commands , $key ); if ( empty ( $commands )) { return ; } $response = new HTTPResponse ( 200 ); $body = array ( '__URI__' => $this ->uri, 'commands' => $commands, 'cursor' => end ( array_keys (self:: $_commands )) + 1 ); $response -> set_body ( $body , true); $this -> write ( $response ); $this ->_cursor = ( int ) end ( array_keys (self:: $_commands )) + 1 ; } ?>
    60. 60. WaterSpout vs Apache/Nginx <ul><li>Neither Apache nor Nginx has a way for one process to notify the listeners </li></ul><ul><ul><li>You need to put the incoming update into some shared location (mysql, memcache, etc) </li></ul></ul><ul><ul><li>Listeners have to poll the shared location </li></ul></ul><ul><ul><ul><li>Heavy </li></ul></ul></ul><ul><ul><ul><li>Slows down timeliness </li></ul></ul></ul><ul><li>WaterSpout solves this by letting updates notify listeners </li></ul>
    61. 61. WebSockets <ul><li>Resources </li></ul><ul><ul><li>http://dev.w3.org/html5/websockets/ </li></ul></ul><ul><ul><li>http://en.wikipedia.org/wiki/Web_Sockets </li></ul></ul><ul><ul><li>http://www.spoutserver.com/ </li></ul></ul>
    62. 62. Questions? <ul><li>Contact </li></ul><ul><ul><li>[email_address] </li></ul></ul><ul><li>Twitter </li></ul><ul><ul><li>@spoutserver </li></ul></ul><ul><li>Feedback </li></ul><ul><ul><li>http://joind.in/talk/view/1748 </li></ul></ul><ul><li>Slides </li></ul><ul><ul><li>http://www.slideshare.net/spoutserver </li></ul></ul>
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×