Il protocollo HTTP tradizionale segue un modello rigido di "richiesta-risposta": il client invia un'istanza, il server risponde e la connessione si chiude. Questo paradigma è perfetto per la navigazione web statica, ma diventa un collo di bottiglia per applicazioni dinamiche come piattaforme di trading, chat live, dashboard IoT o giochi multiplayer. I WebSockets superano questo limite stabilendo un tunnel di comunicazione full-duplex e persistente, permettendo uno scambio di dati istantaneo senza overhead eccessivo.

Come Funzionano i WebSockets

Tutto ha inizio con un "handshake" basato su HTTP. Il client invia un header Upgrade: websocket, chiedendo al server di passare a una connessione WebSocket dedicata. Se il server accetta, risponde con lo stato 101 Switching Protocols. Da quel momento, il canale resta aperto, consentendo a entrambe le parti di scambiarsi pacchetti di dati in modo asincrono, evitando di rinegoziare continuamente gli header HTTP.

Handshake del WebSocket
Client → Server:
GET /chat HTTP/1.1
Host: esempio.it
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Server → Client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Confronto Tecnico: HTTP vs WebSockets

  • HTTP: Basato su richiesta del client, stateless, richiede l'invio di header pesanti a ogni singola richiesta, ideale per REST API.
  • WebSocket: Connessione persistente, bidirezionale, stateful, con un overhead di framing ridotto al minimo (circa 2-14 byte).
  • SSE (Server-Sent Events): Ottimo per flussi di dati unidirezionali dal server al client, costruito direttamente sopra il protocollo HTTP standard.

Implementazione Lato Client

JavaScript (Client-Side)
const ws = new WebSocket("wss://api.esempio.it/ws");

// Apertura canale
ws.addEventListener("open", () => {
  console.log("Connessione stabilita!");
  ws.send(JSON.stringify({ azione: "entra", stanza: "generale" }));
});

// Ricezione dati
ws.addEventListener("message", (event) => {
  const data = JSON.parse(event.data);
  console.log("Dati ricevuti:", data);
});

// Chiusura connessione
ws.addEventListener("close", (event) => {
  console.log(`Disconnesso: ${event.code}`);
});

// Gestione errori
ws.addEventListener("error", (error) => {
  console.error("Errore WebSocket:", error);
});

Server Node.js con la libreria ws

Backend (Node.js)
import { WebSocketServer } from "ws";

const wss = new WebSocketServer({ port: 8080 });

wss.on("connection", (ws) => {
  console.log("Nuovo client connesso");

  ws.on("message", (message) => {
    const data = JSON.parse(message);

    // Broadcast verso tutti gli utenti connessi
    wss.clients.forEach((client) => {
      if (client.readyState === 1) {
        client.send(JSON.stringify({
          tipo: "notifica",
          contenuto: data.text,
          time: new Date().getTime()
        }));
      }
    });
  });

  ws.on("close", () => {
    console.log("Client scollegato");
  });
});

Quando integrare i WebSockets

  • ✅ Ideali per: Applicazioni di messaggistica, sistemi di notifica in tempo reale, editing collaborativo, trading in tempo reale, statistiche sportive live e monitoraggio dispositivi IoT.
  • ❌ Evitare per: Operazioni CRUD standard, download di file, aggiornamenti sporadici (dove il polling o SSE sono più semplici e performanti).

Considerazioni per la Produzione

  • Logica di Riconnessione: Le connessioni possono interrompersi. Implementa sempre un sistema di "exponential backoff" per tentare la riconnessione automatica.
  • Heartbeats (Ping/Pong): Invia pacchetti di controllo periodici per verificare che il client sia ancora attivo e liberare le risorse server bloccate.
  • Autenticazione: Non affidarti esclusivamente ai cookie. Invia token JWT tramite URL o nel primo messaggio di handshake per garantire sicurezza.
  • Scalabilità Orizzontale: Poiché i WebSockets sono stateful, usa sistemi Pub/Sub come Redis o NATS per sincronizzare i messaggi tra più istanze del tuo server.
  • Load Balancer: Assicurati che il tuo bilanciatore di carico supporti l'upgrade del protocollo e le sessioni persistenti.

Prova i Nostri Tool per Sviluppatori

Ottimizza, formatta e valida il tuo codice in un click.