In questa lezione realizzeremo una piccola applicazione per monitorare in tempo reale gli accessi ad un sito Web, sfruttando WebSocket e la libreria ws di Node.js. Creeremo una homepage finta e, ogni volta che un utente richiederà la pagina, il nostro server WebSocket invierà all'amministratore (che visualizzerà una seconda pagina di amministrazione) una notifica di nuovo accesso.
Per realizzare questo esempio dobbiamo implementare sia un normale server web (facendoci aiutare da httpdispatcher) per fornire l'accesso alla homepage e alla pagina di amministrazione sia un server WS che si appoggierà al server web già esistente per offrire i suoi servizi.
Iniziamo dalla logica client-side della pagina di amministrazione:
var newUser = function(data) {
document.getElementById("table").innerHTML +=
"
"+data.time+"
"+data.id+"
"+data.userAgent+"
";
}
var ws = new WebSocket('ws://localhost:1337');
ws.onmessage = function (event) {
newUser(JSON.parse(event.data));
};
Il codice è molto semplice: viene creata una funzione newUser che si occupa di inserire in una tabella una nuova riga inserendo le proprietà timestamp, ip e userAgent del JSON ricevuto e viene istanziato un nuovo oggetto WebSocket (nativo) gestendone la callback onmessage
I messaggi che vengono scambiati tra client e server sono ovviamente stringhe, quindi nel caso si vogliano passare oggetti complessi, la miglior soluzione è quella di usare JSON.stringify
JSON.parse
La logica server-side non è molto più complessa:
var http = require('http'),
dispatcher = require('httpdispatcher'),
WebSocketServer = require('ws').Server;
dispatcher.setStatic('static');
var adminWS = [ ];
var notify = function(req, res) {
for(c in adminWS)
adminWS[c][/c].send(JSON.stringify({
ip: req.connection.remoteAddress,
userAgent: req.headers['user-agent'],
time: (new Date()).getTime()
}));
}
dispatcher.onGet("/homepage", function(req, res) {
res.end("<h1>Homepage</h1");
notify(req, res);
});
var server = http.createServer(function (req, res) {
dispatcher.dispatch(req, res);
});
server.listen(1337, '127.0.0.1');
var wss = new WebSocketServer({server:server});
wss.on('connection', function(ws) {
adminWS.push(ws);
});
Dopo le dovute inclusioni di moduli esterni e la dichiarazione della cartella static
adminWS
La funzione successiva si occupa appunto di ciclare adminWS
req.connection.remoteAddres
req.header['user-agent']
Successivamente viene creato l'entry point della finta home page che oltre a ritornare un HTML banale, invoca la funzione notify definita in precedenza.
Il server Web viene poi istanziato e avviato. Per avviare il server WebSocket
WebSocketServer
Inoltre come callback dell'evento connection viene agganciata una semplice funzione che aggiunge la connessione all'array adminWS.
Ora basterà avviare i server web con node e aprire due tab diverse nel nostro browser (o aprire due browser diversi): da una parte /static/index.html
/homepage
Tutto il codice è scaricabile in allegato.
Conclusioni
Rispetto al modello long-polling, WebSocket è estremamente più semplice