1

Real-time Web Communications

OSCON - Portland, OR

http://spoutserver.com/talks/realtime.html

Scott Mattocks | @scottmattocks | scott@crisscott.com

Thanks http://html5rocks.com

Real-time is important for games…

…and chat…

…and sports

User Expectations

Old Web

  • Lots of data
  • One-way communication
  • User asks for everything

New Web

  • Information as it happens
  • Data flowing in both directions

Problems with Delivery

Timeliness

There shall be no delay in presenting the user with their information.

Problems with Delivery

Efficency

There shall be no wasted bytes.

  • X bytes sent for request (GET headers)
  • Y bytes sent for response (body and headers)
  • Z bytes of new data

  • Z / (X + Y) = efficiency

Problems with Delivery

Efficency

Remeber these for later…

  • GET headers = 410 bytes
  • Response headers = 210 bytes
  • New data = 100 bytes

Problems with Delivery

Scalability

The experience for the first 20 users shall be the same as it is for the first 20,000.

Not Good

Solutions?

  • Short Polling
  • Long Polling
  • Long Polling with 2 servers
  • WebSockets

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);

Short Polling

Arrrgh! Find me some treasure!
Avast! There be no treasure!
  • Nothing can happen until ths ship gets back
  • The faster you poll, the closer you get to real time
  • The faster you poll, the less efficient you are
  • Requires 1 HTTP connection and 1 database connection each time you check for more data

This is not realtime communication.

Short Polling

Where did we go wrong?

  • Extremely innefficient: If 1 in 10 calls yeilds a new message, 1.5% of the data is new message content
  • There are black out periods between and during server calls
  • Uses too many resources
Your sysadmin

Long Polling

function poll_server() {
    new Ajax.Request(this.urlPolling, {
           method:      'post',
           parameters:  data,
           onSuccess:   this.successHandler,
           onFailure:   this.handleFailure,
           onException: this.handleException
        });
}
function successHandler(data) {
    // Do something with the data
    this.poll_server();
}

Long Polling

How do you know when there is new data?

while (true) {
    $data = $db->query($query);
    if ($data) {
        break;
    }
}

If this looks like a good idea to you, please leave now.

Long Polling

Arrrgh! Find me some treasure!
Aye Cap'n, we found some loot!
Ahoy!
  • Nothing can happen until ths ship gets back
  • You send and receive headers along with the data
  • Requires 1 HTTP connection and 1 database connection each time you check for more data

This is not realtime communication.

Long Polling

Where did we go wrong?

  • Slightly more efficient: 13.8% of the data is new message content
  • There are black out periods between server calls
  • Polling on the server is no better than polling on the client
Your sysadmin

Long Polling - 2 servers

We need a way to know when there are updates without polling the database

We can connect to two servers that talk to each other

  • One server sends the main page body
  • One server sends the new messages
  • The main server lets the other server know when a new message arrives

Long Polling - 2 servers

<?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);
}
?>

Long Polling - 2 servers

Where did we go wrong?

  • Efficiency is the same
  • We still have black outs
  • But, the sysadmin isn't as angry

But I can do it all with AJAX!

A 2011 Ford AJAX 150

WebSockets

The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g. using XMLHttpRequest or <iframe>s and long polling). - WebSocket Protocol
WebSockets == Long Polling
(but cooler)

WebSockets

Arrrgh! Find me some treasure!
Aye Cap'n, we found some loot!
Ahoy!
  • After one handshake the money just keeps coming
  • The only thing sent back is treasure (no headers)
  • The connection is always open

This is realtime communication.

WebSockets

Where did we go wrong?

  • Efficiency is 100%: Every byte sent and recieved is meaningful
  • No black outs
  • The sysadmin and the customer are happy
Hint: We didn't go wrong

WebSockets

var ws = new WebSocket(url);
ws.onopen = function() {
     // Called when the connection opens
     };
ws.onmessage = function() {
     // Called when the server sends stuff
     };
ws.onclose = function() {
    // Called when the connection is killed
    };
ws.send('Some awesome data');
// Some time later...
ws.close();

WebSocket Handshake (Client)

GET /demo HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: AQIDBAUGBwgJCgsMDQ4PEC==
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Version: 7

WebSocket Handshake (Server)

HTTP/1.1 101 Switching Protocols
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=

A (Quick) Comparison

Questions?