È uscito il Corso Java Completo
Torna al blog

WebSocket, SSE e polling: come funziona il realtime sul web

Come si costruisce il realtime sul web: polling, long polling, Server-Sent Events e WebSocket a confronto, con i criteri per scegliere la tecnica giusta.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

7 min di lettura

Una chat che si aggiorna da sola, le notifiche che arrivano senza ricaricare la pagina, un documento condiviso dove vedi il cursore degli altri: sono tutte cose che il web, per come è nato, non saprebbe fare. In questo articolo ti spiego le quattro tecniche con cui si ottiene il realtime — polling, long polling, SSE e WebSocket — e come si sceglie quella giusta senza complicarsi la vita.

Il problema di partenza

Il web nasce su un modello in cui è sempre il client a chiedere e il server a rispondere. Il server non può iniziare una comunicazione: se ha una novità per te, non ha modo di dirtela finché non sei tu a domandare.

Tutte le tecniche di realtime esistono per aggirare questo limite. Cambiano in un solo aspetto: chi tiene aperta la conversazione, e per quanto.

Polling: chiedere a intervalli

La soluzione più elementare: il client chiede al server "ci sono novità?" ogni tot secondi.

setInterval(async () => {
  const res = await fetch('/api/messaggi?dopo=' + ultimoId);
  const nuovi = await res.json();
  if (nuovi.length) mostra(nuovi);
}, 5000);

Pro: funziona ovunque, si implementa in cinque minuti, usa normali API REST, non richiede nulla di speciale sul server.

Contro: è intrinsecamente sprecone. Con 1.000 utenti collegati e un intervallo di 5 secondi fai 12.000 richieste al minuto — e la quasi totalità risponde "niente di nuovo". In più il ritardo medio è metà dell'intervallo: con 5 secondi, un messaggio arriva mediamente dopo 2,5.

Quando va benissimo: aggiornamenti che possono aspettare. Lo stato di un ordine, una dashboard che si rinfresca ogni minuto, il progresso di un lavoro lungo. Se un ritardo di qualche secondo non dà fastidio a nessuno, il polling è la scelta giusta — ed è quasi sempre sottovalutato.

Long polling: chiedere e aspettare

Variante più furba: il client chiede, e il server non risponde subito. Tiene la richiesta appesa finché non ha qualcosa da dire (o finché scade un timeout, tipicamente 30 secondi). Appena risponde, il client ne apre subito un'altra.

Il risultato è che i dati arrivano quasi istantaneamente, ma senza richieste a vuoto.

Contro: ogni connessione appesa occupa una risorsa sul server. Su architetture che gestiscono male le connessioni in attesa diventa costoso. È la tecnica che si usava prima dei WebSocket, e oggi sopravvive soprattutto come fallback.

Server-Sent Events: il server che parla

Gli SSE aprono un canale unidirezionale: il server manda dati al client quando vuole, il client ascolta e basta.

const stream = new EventSource('/api/eventi');
stream.onmessage = (e) => mostra(JSON.parse(e.data));

Lato server è testo semplice su una connessione HTTP che resta aperta.

Pro, e sono parecchi:

  • Viaggiano su HTTP normale: nessun problema con proxy, firewall aziendali o load balancer
  • La riconnessione automatica è integrata nel protocollo, non devi scriverla tu
  • Semplicissimi da implementare da entrambi i lati

Contro: il canale va in una direzione sola. Se il client deve mandare dati, lo fa con una normale chiamata HTTP a parte — cosa che in molti casi va benissimo.

Gli SSE sono la tecnologia più sottovalutata delle quattro. Se ti serve che il server spinga aggiornamenti e il client debba solo riceverli, sono quasi sempre la scelta migliore: ottieni il 90% del beneficio dei WebSocket con una frazione della complessità. Non a caso è il meccanismo con cui gli assistenti AI ti mostrano la risposta parola per parola.

WebSocket: il canale bidirezionale

I WebSocket aprono una connessione persistente e bidirezionale: entrambe le parti possono mandare messaggi in qualunque momento, con un overhead minimo per messaggio.

La connessione parte come una normale richiesta HTTP che chiede di "passare" al protocollo WebSocket. Da lì in poi non è più HTTP.

const ws = new WebSocket('wss://esempio.it/socket');
ws.onmessage = (e) => mostra(JSON.parse(e.data));
ws.send(JSON.stringify({ tipo: 'messaggio', testo: 'ciao' }));

Pro: latenza minima, traffico bidirezionale, pochissimo overhead per messaggio. È la scelta obbligata quando servono scambi frequenti in entrambe le direzioni.

Contro, che vanno conosciuti prima di sceglierli:

  • La riconnessione la scrivi tu. Le connessioni cadono — cambio rete, tunnel, sospensione del portatile. Servono logica di riconnessione con attesa progressiva e una coda dei messaggi non inviati.
  • Non funzionano bene con il serverless. Le funzioni serverless sono pensate per richieste brevi, non per connessioni che durano ore. Serve un server persistente o un servizio gestito.
  • Scalare è più complesso. Con più istanze del server, due utenti nella stessa chat possono essere connessi a macchine diverse. Serve un livello di messaggistica condiviso (tipicamente Redis) per far arrivare i messaggi a tutti.
  • Lo stato in memoria è un problema. Se tieni le sessioni nella memoria del processo, un riavvio le perde tutte.

Tabella di confronto

PollingLong pollingSSEWebSocket
DirezioneClient chiedeClient chiedeServer → clientBidirezionale
LatenzaMedia, altaBassaBassaMinima
RiconnessioneNon serveAutomaticaIntegrataDa scrivere
Compatibilità proxyTotaleTotaleOttimaBuona
ServerlessMaleCon limitiNo
ComplessitàMinimaBassaBassaAlta

Come scegliere

Il criterio pratico, in ordine di come lo applicherei:

Il ritardo di qualche secondo è accettabile?Polling. Ordini, dashboard, stato di elaborazioni. Semplice, robusto, funziona ovunque.

Una precisazione utile: se a doversi avvisare sono due server e non un browser, la risposta di solito non è nessuna di queste quattro tecniche ma un webhook — una chiamata HTTP che un servizio fa all'altro quando succede qualcosa. Le tecniche di questo articolo servono a portare i dati fino al browser.

Il server deve spingere aggiornamenti e il client solo ricevere?SSE. Notifiche, feed live, risultati in streaming, barre di avanzamento. È il punto di equilibrio migliore tra beneficio e complessità.

Servono scambi frequenti in entrambe le direzioni?WebSocket. Chat, editor collaborativi, giochi multiplayer, grafici finanziari tick per tick.

L'errore più comune è saltare direttamente ai WebSocket perché suonano come la soluzione "seria". Nella pratica ti ritrovi a gestire riconnessioni, stato distribuito e infrastruttura persistente per un caso d'uso che il polling avrebbe risolto in un pomeriggio. Vale lo stesso ragionamento che faccio in monolite vs microservizi: la complessità va pagata solo quando serve davvero.

Due cose da non dimenticare

L'autenticazione. I WebSocket non portano automaticamente i tuoi header di autenticazione dopo l'apertura. Il token va passato all'inizio e validato in fase di handshake, e va verificato per ogni messaggio che comporta un'azione sensibile. Un canale aperto non è un canale fidato.

Il costo per connessione. Mille connessioni aperte non sono mille richieste: sono mille risorse trattenute nel tempo. Va messo in conto nel dimensionamento, ed è il motivo per cui molti progetti piccoli scelgono un servizio gestito invece di occuparsene in proprio.

In sintesi

Il realtime sul web si ottiene in quattro modi, che si distinguono per chi tiene aperta la conversazione: il polling chiede a intervalli, il long polling chiede e aspetta, gli SSE lasciano parlare il server, i WebSocket aprono un canale in entrambe le direzioni.

Non c'è una tecnica superiore alle altre: c'è quella proporzionata al problema. Il polling è più che sufficiente per moltissimi casi, gli SSE coprono benissimo tutto ciò che è "il server mi avvisa", e i WebSocket servono davvero solo quando il traffico è bidirezionale e frequente.

Parti dalla soluzione più semplice che risolve il tuo caso, e sali di complessità solo quando un limite concreto te lo impone.

Se stai progettando un'applicazione e vuoi impostare bene l'architettura fin dall'inizio, la consulenza per nuovi progetti serve esattamente a evitare scelte che poi costano care.