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!
// 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?
// 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 */
// 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 = [];
}
//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>');
});
//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
// 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
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
}
}
// 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);
// 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' });
});
// 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){ /*...*/ });