Installare Socket.io: app Real-Time
Inviare e ricevere messaggi in tempo reale con Node.js

Tempo di lettura: 6 minuti
Comunicazioni in tempo reale con Socket.io e Nodej.s, guida su come creare un chat server

Installare la socket.io

Nel precedente articolo abbiamo visto cos’è Socket.io e come funziona, ora che conosci tutta la teoria è arrivato il momento di passare alla pratica!

Arriviamo al sodo: come usare Socket.io?

Il primo passo, per quanto possa sembrare ovvio, è quello di installare socket.io. La prima volta che volevo usarlo ho perso ben 15 minuti prima di rendermi conto che avevo dimenticato di eseguire un semplice:

npm install socket.io

Ho appena salvato 15 minuti della tua vita!

Non ringraziarmi, iniziamo a lavorare.

Primo esercizio: connessione

Quando usiamo socket.io, dobbiamo sempre lavorare su due file contemporaneamente:

  • Il file server (es. app.js): è questo che centralizza e gestisce le connessioni dei diversi client collegati al sito.
  • Il file client (ad es. index.html): è questo che si connette al server e visualizza i risultati nel browser.

Il server (app.js)

Ho deliberatamente separato il codice server in due parti: all’inizio, carichiamo il server come di consueto (e recuperiamo e restituiamo il contenuto della pagina index.html); poi, carichiamo socket.io e gestiamo i suoi eventi.

var http = require('http');
var fs = require('fs');

// Carichiamo il file index.html e mostriamo la pagina al visitatore
var server = http.createServer(function(req, res) {
  fs.readFile('./index.html', 'utf-8', function(error, content) {
    res.writeHead(200, {"Content-Type": "text/html"});
    res.end(content);
  });
});

// Carichiamo Socket.io
var io = require('socket.io').listen(server);

// Quando i client si connettono, lo scriviamo nella console
io.sockets.on('connection', function (socket) {
  console.log('Nuovo visitatore connesso!');
});

server.listen(8080);

Questo codice fa 2 cose:

  1. Restituisce il file index.html quando un client visualizza la pagina nel proprio browser.
  2. Si prepara a ricevere le richieste tramite socket.io. Qui ci aspettiamo di ricevere un solo tipo di messaggio: la connessione. Quando ci colleghiamo tramite socker.io, registriamo le informazioni nella console.

Immaginate di essere un visitatore.

Apri il tuo browser dove si trova l’ applicazione (http://localhost:8080 in questo caso). Vi inviamo il file index.html, la pagina carica. In questo file, che vedremo tra un minuto, un codice JavaScript si connette al server, questa volta non tramite il protocollo http ma tramite Socket.io (quindi solitamente via WebSockets).

Il cliente effettua 2 tipi di connessioni:

  1. Una connessione “classica” al server HTTP per caricare la pagina index.html.
  2. Una connessione “in tempo reale” per aprire un tunnel via WebSockets grazie a socket.io.

Il client (index.html)

Ora guardiamo il client. Il file index.html viene inviato dal server Node.js. Si tratta di un file HTML classico, l’ unica differenza è che contiene un po’ di JavaScript che permette la comunicazione in tempo reale con il server tramite socket.io:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Socket.io</title>
</head>
<body>
  <h1>Aperta una comunicazione tramite Socket.io!</h1>
  <script src="/socket.io/socket.io.js"></script>
  <script>
  var socket = io.connect('http://localhost:8080');
  </script>
</body>
</html>

Ho volutamente messo il codice JavaScript alla fine del codice HTML. Naturalmente, avrei potuto metterlo nel tag <head> come molti, ma posizionandolo alla fine del codice HTML si evita di interferire con il caricamento della pagina (con la parvenza di un caricamento più veloce).

Analizziamo il codice: in primo luogo, recuperiamo il file socket.io.js dal server. Questo ti viene fornito automaticamente nel server Node.js tramite il modulo socket.io (in modo che il percorso del file non sia scelto a caso):

<script src="/socket.io/socket.io.js"></script>

Il contenuto di questo script permette  la gestione della comunicazione da client verso server (e viceversa), sia con i WebSockets sia con uno dei vecchi metodi in caso di browser obsoleti (es. Ajax, ecc).

In seguito, possiamo eseguire azioni lato client e comunicarle al server. Per il momento, abbiamo fatto qualcosa di molto semplice: ci siamo semplicemente connessi al server.

Dato che il server gira in locale, l’indirizzo è http://localhost:8080. Ovviamente, sul web, il percorso dovrà essere adattato per mostrare l’ indirizzo del tuo sito web (es. http://mysite.com).

var socket = io.connect('http://localhost:8080');

Testiamo il codice!

L’unica cosa che devi fare è avviare l’app:

node app.js

Possiamo poi andare al nostro browser a questo indirizzo Node.js: http://localhost:8080.

Verrà caricata una pagina di base. Il computer aprirà quindi una connessione con socket.io:

connessione.socket-io-nodejs-client
Connessione con Socket.io avvenuta correttamente.

Ottimo! Questo significa che il nostro codice funziona.

Per il momento non fa nulla di straordinario, ma abbiamo le basi. Ora è il momento di iniziare a scambiare messaggi con il server!

Invio e ricezione di messaggi

Ora che il client è connesso, possiamo scambiare messaggi tra il client e il server. Ci sono 2 possibili scenari:

  1. Il server vuole inviare un messaggio al client.
  2. Il client desidera inviare un messaggio al server.

Inviare messaggi dal Server al Client

Facciamo qualcosa di semplice: il server invia un messaggio al client quando si connette, per confermare che la connessione ha funzionato correttamente. Aggiungi questo al file app.js:

io.sockets.on('connection', function (socket) {
  socket.emit('message', 'Sei connesso amico!');
});

Quando rileviamo una connessione, inviamo un messaggio al client con socket.emit(). La funzione richiede 2 parametri:

  • Il tipo di comunicazione che vogliamo trasmettere. In questo caso, il mio messaggio è di tipo “message” (non sono molto creativo, lo so). In questo modo è possibile distinguere tra i diversi tipi, ad esempio in un gioco, potremmo inviare cominicazioni di tipo “move_player“,”attack_player“, e cosi via.
  • Il contenuto del messaggio. Puoi inserire tutto quello che vuoi.

Se la tua comunicazione include diversi tipi di dati puoi raggruppali sotto forma di oggetti, come questo:

socket.emit('message', { content: 'Sei connesso amico!', importance: '1' });

Sul lato del file index.html (il client) ascolteremo i messaggi di tipomessage” in arrivo:

<script>
  var socket = io.connect('http://localhost:8080');
  socket.on('message', function(message) {
    alert('Il server dice: ' + message);
  });
</script>

Con socket.on(), ascoltiamo le comunicazioni di tipo “message”. Quando arrivano comunicazioni, richiamiamo la funzione callback che, in questo caso, visualizza una semplice finestra di dialogo.

Provalo. Vedrai che quando si carica la pagina index.html, verrà visualizzata una finestra di dialogo che ti dice che la connessione ha avuto successo.

esempio-socket-io-nodejs-comuncazioni-da-server-a-client
Il client mostra il messaggio ricevuto dal server!

Inviare messaggi dal Client al Server

Ora  facciamo il contrario!

Perché non aggiungiamo un pulsante nella pagina?

Appena qualcuno clicca il pulsante, noi inviamo un messaggio al server.

Lato client (index.html), aggiungiamo un pulsante tipo “Suona il campanello”. Facendo clic su di esso viene inviato un messaggio al server, semplice.

Ecco il codice completo:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Socket.io</title>
</head>
<body>
  <h1>Aperta una comunicazione tramite Socket.io!</h1>

  <p>
    <input type="button" value="Suona il campanello" id="poke" />
  </p>
  
  <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script src="/socket.io/socket.io.js"></script>
  <script>
    var socket = io.connect('http://localhost:8081');
    socket.on('message', function(message) {
      alert('Il server dice: ' + message);
    });

   $('#poke').click(function () {
     socket.emit('message', 'Hey server, ci sono anch\'io!');
   });
  </script>
</body>
</html>

Ho incluso jQuery per motivi pratici, cosi possiamo catturare facilmente il click del pulsante, ma non è obbligatorio (puoi farlo tranquillamente in Javascript Vanilla).

Infine, l’unica parte nuova ed emozionante codice è questa:

$('#poke').click(function () {
  socket.emit('message', 'Hey server, ci sono anch\'io!')
})

È molto semplice. Facendo clic sul pulsante si invia una comunicazione di tipo “message” al server, insieme al  suo contenuto.

Per recuperare questa informazione dal lato server, dobbiamo metterci in ascolto di un evento di tipo “message”:

io.sockets.on('connection', function (socket) {
  socket.emit('message', 'Sei connesso amico!');

  // Quando il server riceve una comunicazione di tipo "message" dal client 
  socket.on('message', function (message) {
      console.log('Un visitatore ha suonato il campanello! Dice:' + message);
  }); 
});

Ottimo! Avvia il codice!

Fai clic sul pulsante e guarda la console del server. Dovrebbe apparire la scritta:

Un visitatore ha suonato il campanello! Dice: Hey server, ci sono anch'io!
weboscket-nodejs-socket-io-comunicazioni-da-client-a-server
Esempio di comunicazione dal Client verso il Server.

Quando un client clicca sul pulsante, il server reagisce immediatamente sulla console.

 


L’articolo che hai appena letto fa parte di una lunga serie di guide e tutorial tradotte in italiano e distribuite gratuitamente. In particolare questo articolo si basa sui testi inglesi di Mathieu Nebra (Ultra fast applications using Node.js), con licenza CC BY-NC-SA. Questo articolo è sotto la stessa licenza.