technologies of
the real time web

In this talk you'll get a deep dive into the inner workings that drive the real-time web. We'll have a look at the technologies, the fallbacks and the complete frameworks and services that enable you to go real-time today! Basically we're talking about the what, the why and the how of real-time web and you'll be familiarised with concepts like sockets, server sent events, NodeJS and SignalR!


tv.nrk.no / radio.nrk.no

Intelligent Polling    =>    SignalR
Azure Service Bus

The real time what?


its not just web sockets

Real Time is a concept

The ability for your server-side code
to push content to connected clients


HTTP Polling    

LiveConnect (applet/js)

Forever Frame

AJAX
(thank MS and Outlook!)

Long Polling 

XHR Streaming / multipart-replace 

COMET


umbrella term for HTTP hacks to simulate bi-directional communication between client and server.

[forever frame, long polling, script tag polling]

requires two HTTP connections
one for sending and one for recieving

Same Domain Policies
(have to self host)

The why?


Better User Experience
  • data driven pages
  • single page apps
  • bigger engagement
  • bigger exposure


when now is a must

its business critical / what you do

news/stock tickers

messaging apps

status updates

games

cost reduction


cut HTTP overhead

less bandwidth usage

less hardware stress

actual income


conversion rate?

more clients?

the how!

  • polling
  • long polling
  • forever frames
  • SSE
  • sockets
  • webRTC


Polling


check server for updates at regular intervals

request-response-model


set interval

// client
setInterval(function(){
    $.ajax({ url: "poll" })
    .done(function (data) {
        // do something with data
    });
}, 15000);

// server
app.get('/poll', function (req, res) {
    var data = getDataUpdates();
	
    if(!!data){
        res.write(data);
    } 
	
    res.end();
});

What if server does not respond in 15s?

set timeout


// client
(function poll () { // a self invocating closure
    setTimeout(function () {
        $.ajax({ url: 'poll' })
        .done(function (data) { 
            // do something with data, then...
            poll();
        });
    }, 15000);
}());

// server

/* same as for setInterval */

A lot of wasted connections 

long polling

[ hanging get / COMET]

establish connection and wait

server responds when it has new data

if connection is closed, client re-establishes

implementation

// client
(function poll(){
  $.ajax({ url: 'longpoll', timeout: 15000})
  .done(function (data){
    // do someting with data
  }).always(poll);
});

// server
var defers = [];
app.get('/longpoll', function (req, res) {
  // save response in array
  defers.push(res);
});

function whenDataHappens(data){
  for(idx in defers){
    defers[idx].send(data);
  }
  defers = [];
}


downsides

Data could be lost during reconnect

Browser support for simultaneous connections

Hanging Get not good for all servers

Not really true server push

forever frame


true push without polling

HTTP 1.1 incremental rendering support

avoids HTTP and TCP/IP set-up and tear-down


Chunked encoding

HTTP 1.1 allows sending a response 
before knowing its total length

Header: "Transfer-Encoding:  chunked"
//server
var clients = [];
app.get('/foreverframe', function (req, res) {
    clients.push(res);

    res.writeHead(200, {
        'Content-Type':'text/html', 
        'Transfer-Encoding':'chunked'}
    );
    var msg = "connected via iframe!";
    res.write('<script>parent.ondata("'+msg+'");</script>');
});
data-chunks wrapped in script-tags

hidden iframes

open after page load 

script-tags executed as they are recieved
//client

<iframe src=""></iframe>
<script>
    window.ondata = function(data){
        // do something wit data
    }
    $(function(){
        $('iframe').attr('src', '/foreverframe');

    });
</script>

all in all - its a hack

Server sent events

true event-based server push

shadowed by WebSockets

browser subscribe to stream of updates

Fancyful built-in functionality
  • automatic reconnects
  • event id's
  • arbitrary events

server side

// nodejs + express

var clients = [];
app.get('/stream', function(req, res){
    var id = (new Date()).toLocalTimeString();
    clients.push({res : res, id : id});
    res.writeHead(200,{
        'Content-Type' : 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection'   : 'keep-alive'        
    });
    sendMessage(res, 'connected to server');
});
function sendMessage(res, msg){
    res.write('data: ' + msg + '\n\n');
}

client side

// client
if(!!EventSource){

  var source = new EventSource('/stream');
  
  source.onmessage = function(e){
    // do something with e.data
  }

  source.onopen = function(e){
    // called when connection opened
  }

  source.onerror = function(e){
    // called on error
  }

}

JSON & custom events

// server
app.get('/stream', function(){
    // first write headers, then...

    res.write('id: ' + (new Date).getTime() + '\n');
    res.write('event: customevent');
    res.write('data: {\n');
    res.write('data: "msg" : "hey SSE" \n');
    res.write('data: }\n\n');

})
// client
var source = new EventSource('/stream');

source.addEventListener('customevent', function(e){

    var data = JSON.parse(e.data);
    var eventId = e.lastEventId;

}, false);


HTTP based so works on all servers

Browser Support 
  • FF > 6.0
  • Chrome
  • Opera < 11
  • Safari > 5.0

i.e. Long Polling or Forever Frame for IE

web sockets


Long-held, full-duplex single TCP connection

Network traffic comparison

1,000 clients polling/recieve once a second

  • http: 871,000 bytes = 6.6 Mbps
  • ws:    2,000       bytes = 0.015 Mbps

client side

// vanilla js

var connection = new WebSocket('ws://some-server', ['soap','xmpp']);
connection.onopen = function() {
    connection.send('hey Im here!'); // string or binary data
}
connection.onmessage = function(){};
// using socket.io

var socket = io.socket('http://some-server');

socket.on('named event', function(data){
    // do something with data
    socket.emit('another event', { msg: 'hola' });
});


server

// using nodejs
var app = require('express')(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server);

server.listen(3000);

// setup socket
io.sockets.on('connection', function(socket){

    socket.on('another event', function(data){
        console.log(data.msg);
    });
    socket.emit('named event', { msg : 'connected' })

});
// routing
app.get('/', function(req, res){ /*...*/ });


are we ready?

Can we skip HTTP solutions?

  1. Need greater browser support

  2. Anti-virus manufacturers (such as Avast!) 
    stop interfering with connectivity

  3. Internet infrastructure is updated. 
    We want port 80 (WS), not just 443 (WSS).
    (some mobile carriers block WS)

web rtc


Imagine a world where your phone, 
TV and computer could all 
communicate on a common platform. 

Imagine it was easy to add video chat 
to your web application. 
That's the vision of WebRTC

Open standards for real-time, plugin-free video,
audio and data communication.

Current api


  • MediaStream (aka getUserMedia)
  • RTCPeerConnection
  • RTCDataChannel

browser-to-browser communication

solutions

Bundles with automatic fallback




Services

$6k/month for 50k connections

$400/month for 10k connections

$2k/month unlimited connections

Reference


TECHNOLOGIES OF THE REAL TIME WEB

By Tobias Lundin

TECHNOLOGIES OF THE REAL TIME WEB

A deep dive into the inner workings that drive the real-time web. The technologies, the fallbacks and the complete frameworks and services that enable you to go real-time now!

  • 2,353