SSE — cos’è, Server-Sent Events e streaming unidirezionale

Autore: IT Sectr Pubblicato: 2026-06-02 Tempo di lettura: 8 min

SSE (Server-Sent Events) è uno standard W3C che consente al server di inviare dati in streaming al client attraverso una singola connessione HTTP in modalità unidirezionale. A differenza di WebSocket, SSE funziona su HTTP normale e non richiede un protocollo speciale o librerie lato client. Secondo la specifica W3C HTML Living Standard (2025), l’API EventSource è supportata in tutti i browser moderni, inclusi Chrome, Firefox, Safari ed Edge.

Punti chiave

  • SSE è uno standard per il trasferimento unidirezionale di dati dal server al client tramite connessione HTTP.
  • API EventSource è un’interfaccia browser integrata per ricevere SSE senza librerie esterne.
  • Riconnessione automatica — il browser ripristina automaticamente la connessione in caso di interruzione.
  • Protocollo di testo — i dati vengono trasmessi in formato text/event-stream con un formato di testo semplice.
  • Comunicazione unidirezionale — SSE è adatto per notifiche, feed di notizie, ticker e monitoraggio, ma non per chat.

Cos’è SSE?

SSE (Server-Sent Events) è una tecnologia che consente a un server web di inviare dati al client in qualsiasi momento dopo aver stabilito una connessione. È standardizzata da WHATWG come parte dell’HTML Living Standard e utilizza il tipo MIME text/event-stream. SSE supporta la trasmissione di dati di testo con la possibilità di specificare un identificatore di messaggio, un tipo di evento e un ritardo di riconnessione.

A differenza di WebSocket, che richiede un protocollo bidirezionale e una richiesta di upgrade, SSE funziona su HTTP normale. Il server imposta l’intestazione Content-Type: text/event-stream, invia i dati a pezzi e mantiene la connessione aperta. Il client riceve i dati tramite l’API EventSource del browser, che analizza automaticamente lo stream e genera eventi.

Secondo CanIUse (2025), l’API EventSource è supportata nel 97,5% dei browser a livello globale. Non è supportata in Internet Explorer e in alcuni browser mobili (Samsung Internet prima della versione 7.0). Per questi casi, esistono polyfill che emulano EventSource tramite XHR streaming. SSE non funziona con HTTP/1.1 pipelining, ma è completamente compatibile con HTTP/2 server push.

Storia e standardizzazione

SSE è stato proposto come parte della specifica HTML5 nel 2009 con il nome Server-Sent DOM Events. La prima implementazione è apparsa in Opera 9.0, poi in Firefox 6.0 (2011), Chrome 9.0 (2011) e Safari 5.0 (2010). Nel 2015, la specifica è stata spostata in una sezione separata dell’HTML Living Standard. Nonostante un decennio di storia, SSE rimane meno popolare di WebSocket a causa della sua natura unidirezionale.

Come funziona SSE

Il funzionamento di SSE è il seguente: il client crea un’istanza di EventSource con l’URL dell’endpoint del server. Il browser invia una richiesta GET con l’intestazione Accept: text/event-stream. Il server risponde con stato 200 OK e l’intestazione Content-Type: text/event-stream, quindi inizia a inviare dati in formato event-stream. La connessione rimane aperta fino a quando il server non invia un segnale di terminazione o il client chiama close().

Sul lato server, i dati vengono inviati a pezzi (chunked transfer encoding). Ogni pezzo di dati è un messaggio di testo composto da righe di campi (event, data, id, retry). Il server può inviare messaggi in qualsiasi momento, rendendo SSE ideale per notifiche e aggiornamenti di stato. La connessione non richiede un costante scambio di pacchetti heartbeat (come WebSocket), sebbene il campo retry controlli la frequenza di riconnessione.

Secondo test di prestazioni (2024), SSE fornisce un throughput fino a 10.000 messaggi al secondo per connessione con una dimensione del messaggio di 256 byte. Sul lato server, ogni connessione SSE consuma circa 5–10 KB di memoria, consentendo a un server di supportare oltre 50.000 connessioni simultanee con 1 GB di RAM. Questo è significativamente meno di WebSocket a causa dell’assenza di un protocollo binario.

Formato event-stream

Il formato text/event-stream è un semplice protocollo di testo in cui ogni messaggio è costituito da campi denominati separati da caratteri di nuova riga. Ogni campo ha il formato “NomeCampo: valore”. I messaggi sono separati da due caratteri di nuova riga (\n\n).

Campi supportati: event (tipo di evento, default message), data (stringa di dati, può essere multilinea), id (ultimo identificatore di evento, memorizzato in Last-Event-ID), retry (tempo di riconnessione in millisecondi). I commenti iniziano con due punti (:) e vengono ignorati dal parser, ma possono essere utilizzati per heartbeat.

CampoObbligatorioScopo
eventNoTipo di evento (default message)
dataStringa di dati del messaggio
idNoIdentificatore di evento per Last-Event-ID
retryNoRitardo di riconnessione in ms

Esempio di event-stream

text
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001

event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000

event: close
data: Session ended

API EventSource sul client

L’API EventSource è un’interfaccia browser integrata per ricevere SSE. Per creare una connessione, è sufficiente chiamare il costruttore con l’URL dell’endpoint. EventSource stabilisce automaticamente la connessione, gestisce la riconnessione e analizza i messaggi in arrivo in eventi JavaScript.

Eventi EventSource: open (connessione stabilita), message (messaggio ricevuto senza evento specificato), error (errore di connessione). Per eventi personalizzati (event: custom), puoi usare addEventListener con il nome dell’evento. EventSource invia automaticamente l’intestazione Last-Event-ID durante la riconnessione, consentendo al server di riprendere lo stream dal punto in cui è stato interrotto.

Secondo la documentazione MDN (2025), EventSource supporta CORS e la trasmissione di credenziali (withCredentials). EventSource non è adatto per inviare intestazioni personalizzate o corpi di richiesta — è necessaria un’implementazione manuale tramite fetch + ReadableStream. EventSource non supporta dati binari — solo testo e JSON.

Codice JavaScript lato client

js
const eventSource = new EventSource('/api/events/stream');

eventSource.addEventListener('open', () => {
    console.log('Connessione SSE aperta');
});

eventSource.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Ricevuto:', data);
    renderUpdate(data);
});

eventSource.addEventListener('notification', (event) => {
    const notification = JSON.parse(event.data);
    showNotification(notification.text);
});

eventSource.addEventListener('error', (error) => {
    console.error('Errore SSE:', error);
    // Il browser si riconnette automaticamente
});

// Chiudi connessione
eventSource.close();

SSE vs WebSocket: confronto

SSE e WebSocket sono tecnologie diverse per la comunicazione in tempo reale, ciascuna con i propri punti di forza. WebSocket è adatto per lo scambio bidirezionale di dati (chat, giochi, editing collaborativo), mentre SSE è per flussi unidirezionali dal server al client (notifiche, feed di notizie, ticker).

La differenza principale è che WebSocket richiede una richiesta di upgrade da HTTP/1.1 al protocollo WebSocket (ws://), che può essere bloccata dai proxy aziendali. SSE funziona su HTTP normale, passa attraverso qualsiasi proxy e non richiede configurazione speciale del server. SSE è anche più semplice da implementare — il server non necessita di librerie aggiuntive, basta formattare correttamente la risposta HTTP.

Secondo test comparativi (2024), su un singolo processo server, SSE supporta il 30–50% in più di connessioni rispetto a WebSocket grazie al protocollo più semplice. Tuttavia, SSE ha una latenza maggiore (50–200 ms contro 10–50 ms di WebSocket) perché SSE utilizza HTTP chunked anziché un flusso bidirezionale completo con frame binari.

CaratteristicaSSEWebSocket
DirezioneServer → clientBidirezionale
ProtocolloHTTP (text/event-stream)ws:// / wss:// (RFC 6455)
Browser97,5% (EventSource integrato)97% (WebSocket integrato)
DatiSolo testo / JSONTesto + binario (Blob, ArrayBuffer)
ProxyPassa attraverso qualsiasi proxyRichiede configurazione proxy
RiconnessioneAutomatica (browser)Implementazione manuale
CronologiaLast-Event-IDNessuna cronologia integrata

Come implementare SSE sul server

Implementare SSE sul server non richiede librerie — basta impostare le intestazioni HTTP corrette e inviare dati in formato text/event-stream. Vediamo un esempio in Node.js utilizzando il modulo http integrato. Il server imposta le intestazioni Content-Type e Cache-Control, quindi invia messaggi ogni N secondi.

Secondo MDN Web Docs (2025), le intestazioni necessarie per SSE sono: Content-Type: text/event-stream, Cache-Control: no-cache e Connection: keep-alive. Senza Cache-Control, il browser potrebbe memorizzare nella cache lo stream SSE, interrompendo la consegna. Connection: keep-alive indica esplicitamente al browser di mantenere la connessione aperta.

Codice server in Node.js

js
const http = require('http');

http.createServer((req, res) => {
    res.writeHead(200, {
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive'
    });

    let eventId = 0;
    const interval = setInterval(() => {
        eventId++;
        res.write(`id: ${eventId}\n`);
        res.write(`event: update\n`);
        res.write(`data: {"time": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
    }, 2000);

    req.on('close', () => {
        clearInterval(interval);
    });
}).listen(3000);

SSE in Python (Flask)

python
from flask import Response, Flask
import time
import json

app = Flask(__name__)

@app.route('/stream')
def stream():
    def generate():
        event_id = 0
        while True:
            event_id += 1
            data = json.dumps(
                {'ticker': 'AAPL', 'price': 150.25})
            yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
            time.sleep(1)
    return Response(generate(),
        mimetype='text/event-stream')

SSE nelle app mobili

L’uso di SSE nelle app mobili è limitato dalla mancanza di un’implementazione nativa di EventSource per iOS e Android. Sulle piattaforme mobili, SSE viene implementato tramite librerie di terze parti: su iOS — via URLSession con NSURLProtocol, su Android — via OkHttp con supporto SSE (okhttp-sse). Per React Native e Flutter, sono disponibili pacchetti che emulano EventSource.

Su iOS, l’implementazione nativa di SSE è possibile tramite URLSessionDataDelegate. Quando riceve dati nel metodo urlSession(_:dataTask:didReceive:), l’app accumula un buffer e analizza manualmente il formato event-stream. Secondo il blog di sviluppo iOS (2024), il consumo della batteria con SSE su iOS è inferiore del 40% rispetto a una connessione WebSocket costante a causa dell’assenza di pacchetti heartbeat.

Su Android, OkHttp fornisce la classe EventSource.Factory per iscriversi agli stream SSE. Le app Android possono utilizzare SSE per notifiche quando FCM non è disponibile o per la sincronizzazione dei dati in background. SSE su Android funziona bene con WorkManager per attività di background di lunga durata. Secondo la documentazione OkHttp (2025), okhttp-sse supporta la riconnessione automatica con un listener personalizzato.

Domande frequenti

In cosa SSE differisce da WebSocket?

SSE è trasmissione unidirezionale (server → client) su HTTP, non richiede librerie sul client. WebSocket è trasmissione bidirezionale con protocollo binario. SSE è più semplice da implementare, WebSocket è adatto per attività in cui anche il client invia dati.

SSE supporta dati binari?

No, SSE trasmette solo dati di testo. Per dati binari (immagini, audio), è necessaria la codifica Base64, che aumenta la dimensione del 33%. Per flussi binari, è meglio usare WebSocket.

Come gestisce SSE le interruzioni di connessione?

EventSource si riconnette automaticamente in caso di interruzione. Il tempo di ritardo è impostato dal campo retry nello stream (default 1000 ms). Durante la riconnessione, il browser invia l’intestazione Last-Event-ID, consentendo al server di riprendere lo stream dal punto in cui è stato interrotto.

Quante connessioni SSE può mantenere un browser?

Ogni browser ha un limite sul numero di connessioni HTTP simultanee a un dominio. Per HTTP/1.1 — 6–8 connessioni per dominio, per HTTP/2 — fino a 100. SSE utilizza una connessione, quindi non c’è concorrenza con altre richieste.

Si può usare SSE per la chat?

SSE è adatto solo per ricevere messaggi (in arrivo). Per inviare messaggi (in uscita), è necessaria una richiesta HTTP separata (POST). Per una chat completa, è più conveniente utilizzare WebSocket o Socket.IO con comunicazione bidirezionale in una singola connessione.

Riepilogo

  • SSE è uno standard per il trasferimento unidirezionale di dati dal server al client tramite una connessione HTTP standard senza librerie aggiuntive.
  • API EventSource è un’interfaccia browser integrata supportata dal 97,5% dei browser moderni.
  • Semplice protocollo di testo text/event-stream con i campi event, data, id e retry.
  • Riconnessione automatica con supporto Last-Event-ID per riprendere lo stream dal punto in cui è stato interrotto.
  • Efficienza — SSE supporta più connessioni server (50.000+) rispetto a WebSocket grazie al protocollo più semplice.
  • Su piattaforme mobili SSE viene implementato tramite OkHttp (Android) o URLSession (iOS) con analisi manuale dello stream.
  • Per flussi unidirezionali (notifiche, feed, ticker) scegli SSE, per comunicazione bidirezionale — WebSocket o Socket.IO.

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche