Uno dei principali catalizzatori della tecnologia WebSocket, che ne ha facilitato significativamente la diffusione (congiuntamente ad altri fattori), è il crescente successo di Node.js, il noto framework che ci consente di implementare sia la logica client che quella server di un'applicazione web utilizzando un unico linguaggio di programmazione: JavaScript. Su HTML.it è disponibile una esauriente guida a Node.js; nel seguito ci limiteremo semplicemente a descrivere come implementare un WebSocket server utilizzando questo framework.
Esistono moltissime soluzioni per implementare un WebSocket server con Node.js. Quella che descriveremo qui di seguito e su cui ci concentreremo, WebSocket-Node, si avvicina molto (come già successo con i linguaggi di programmazione visti in precedenza) ai principi su cui si basa la sintassi utilizzata nativamente su JavaScript per implementare il lato client delle WebSocket.
La prima cosa da fare sarà l'installazione. Possiamo ricorrere, a tal fine, ad npm, il tool che ci permette di accedere facilmente ai repository di Node.js:
npm install websocket
In questo modo non dovremo far altro che eseguire un unico comando, e l'installazione verrà effettuata in maniera automatica. L'unica nota che vale la pena aggiungere riguarda gli utenti Windows: per installare questa libreria, infatti, sono richiesti Microsoft Visual C++ e Python 2.7, come specificato sulla pagina di GitHub del progetto.
A questo punto, vediamo subito il codice:
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
// Qui possiamo processare la richiesta HTTP
// Dal momento che ci interessano solo le WebSocket, non dobbiamo implementare nulla
});
server.listen(1337, function() { });
// Creazione del server
wsServer = new WebSocketServer({
httpServer: server
});
// Gestione degli eventi
wsServer.on('request', function(request) {
var connection = request.accept(null, request.origin);
connection.on('message', function(message) {
// Metodo eseguito alla ricezione di un messaggio
if (message.type === 'utf8') {
// Se il messaggio è una stringa, possiamo leggerlo come segue:
console.log('Il messaggio ricevuto è: ' + message.utf8Data);
}
});
connection.on('close', function(connection) {
// Metodo eseguito alla chiusura della connessione
});
});
Nella prima parte del codice appena mostrato, non facciamo altro che istanziare un server HTTP, che utilizziamo come parametro di inizializzazione di un oggetto WebSocketServer
. A questo punto, tutte le volte che sarà effettuata una richiesta al server, essa verrà accettata e ne sarà gestita la ricezione dei messaggi tramite l'evento message
dell'oggetto connection
.
Abbiamo anche la possibilità, ovviamente, di inviare messaggi dal server verso il client. Per inviare una stringa, possiamo utilizzare il metodo sendUTF
dell'oggetto connection
:
connection.sendUTF("Stringa di esempio");
Una delle principali differenze rispetto agli esempi con altri linguaggi di programmazione, è la possibilità di inviare e ricevere messaggi di tipo binario, rappresentati cioè come stringhe di byte. Per farlo, analizziamo il seguente frammento di codice:
if (message.type === 'binary') {
console.log('Messaggio di dimensione: ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
Quando riceviamo un messaggio, possiamo verificare se esso è binario ('binary'
) o se è una stringa ('utf8'
) tramite il campo type
dell'oggetto message
. Nel primo caso, il campo binaryData
di message
conterrà l'array di byte rappresentante il messaggio stesso, che possiamo leggere, modificare, ed eventualmente (come in questo esempio) inviare nuovamente, sempre in forma binaria, tramite il metodo sendBytes
dell'oggetto connection
.
Alternative disponibili per Node.js
Oltre a WebSocket-Node, Node.js offre moltissime soluzioni alternative in grado di implementare un WebSocket server. Una di esse, chiamata ws, è già stata tratta su HTML.it nella guida a Node.js. Insieme ad essa, vale la pena citarne qualche altra: