SSE — ce este, Server-Sent Events și streamingul unidirecțional

Autor: IT Sectr Publicat: 2026-06-02 Timp de citire: 8 min

SSE (Server-Sent Events) — standardul W3C care permite serverului să trimită date în flux clientului printr-o singură conexiune HTTP în mod unidirecțional. Spre deosebire de WebSocket, SSE funcționează pe HTTP obișnuit și nu necesită un protocol special sau bibliotecă pe partea clientului. Conform specificației W3C HTML Living Standard (2025), EventSource API este suportat în toate browserele moderne, inclusiv Chrome, Firefox, Safari și Edge.

Principalele puncte

  • SSE — standard de transmitere unidirecțională a datelor de la server la client printr-o conexiune HTTP.
  • EventSource API — interfață browser încorporată pentru recepționarea SSE fără biblioteci externe.
  • Reconectare automată — browserul restabilește automat conexiunea la întrerupere.
  • Protocol textual — datele sunt transmise în format text/event-stream cu un format text simplu.
  • Comunicare unidirecțională — SSE este potrivit pentru notificări, fluxuri de știri, tickere și monitorizare, dar nu pentru chat-uri.

Ce este SSE?

SSE (Server-Sent Events) — tehnologie care permite serverului web să trimită date clientului în orice moment după stabilirea conexiunii. Este standardizată de WHATWG ca parte a HTML Living Standard și utilizează tipul MIME text/event-stream. SSE suportă transmiterea datelor text cu posibilitatea de a specifica un identificator de mesaj, tipul evenimentului și întârzierea reconectării.

Spre deosebire de WebSocket, care necesită un protocol bidirecțional și o cerere de upgrade, SSE funcționează pe HTTP obișnuit. Serverul setează antetul Content-Type: text/event-stream, trimite datele în porțiuni și menține conexiunea deschisă. Clientul primește datele prin EventSource API al browserului, care parsează automat fluxul și generează evenimente.

Conform datelor CanIUse (2025), EventSource API este suportat în 97.5% din browsere la nivel global. Nu este suportat în Internet Explorer și unele browsere mobile (Samsung Internet până la versiunea 7.0). Pentru aceste cazuri există polyfill-uri care emulează EventSource prin XHR streaming. SSE nu funcționează cu HTTP/1.1 pipelining, dar este complet compatibil cu HTTP/2 server push.

Istorie și standardizare

SSE a fost propus ca parte a specificației HTML5 în 2009 sub numele de Server-Sent DOM Events. Prima implementare a apărut în Opera 9.0, apoi în Firefox 6.0 (2011), Chrome 9.0 (2011) și Safari 5.0 (2010). În 2015, specificația a fost separată într-o secțiune distinctă a HTML Living Standard. În ciuda unei istorii de zece ani, SSE rămâne mai puțin popular decât WebSocket datorită naturii sale unidirecționale.

Cum funcționează SSE

Mecanismul de funcționare SSE este următorul: clientul creează o instanță EventSource cu URL-ul endpoint-ului serverului. Browserul trimite o cerere GET cu antetul Accept: text/event-stream. Serverul răspunde cu statusul 200 OK și antetul Content-Type: text/event-stream, după care începe să trimită date în format event-stream. Conexiunea rămâne deschisă până când serverul trimite un semnal de terminare sau clientul apelează close().

Pe partea serverului, datele sunt trimise în porțiuni (chunked transfer encoding). Fiecare bloc de date este un mesaj text format din linii de câmpuri (event, data, id, retry). Serverul poate trimite mesaje în orice moment, ceea ce face SSE ideal pentru notificări și actualizări de stare. Conexiunea nu necesită schimb constant de pachete heartbeat (ca WebSocket), deși câmpul retry controlează frecvența reconectării.

Conform datelor testelor de performanță (2024), SSE asigură un throughput de până la 10 000 de mesaje pe secundă per conexiune la o dimensiune a mesajului de 256 de octeți. Pe partea serverului, fiecare conexiune SSE consumă aproximativ 5–10 KB de memorie, permițând unui singur server să suporte 50 000+ de conexiuni simultane cu 1 GB RAM. Acest lucru este semnificativ mai puțin decât WebSocket din cauza absenței unui protocol binar.

Formatul event-stream

Formatul text/event-stream — un protocol text simplu în care fiecare mesaj constă din câmpuri denumite separate prin caractere de linie nouă. Fiecare câmp are formatul «NumeCâmp: valoare». Mesajele sunt separate prin două caractere de linie nouă ( ).

Câmpuri suportate: event (tipul evenimentului, implicit message), data (șir de date, poate fi multiline), id (ultimul identificator de eveniment, stocat în Last-Event-ID), retry (întârzierea reconectării în milisecunde). Comentariile încep cu două puncte (:) și sunt ignorate de parser, dar pot fi folosite pentru heartbeat.

CâmpObligatoriuScop
eventNuTipul evenimentului (implicit message)
dataDaȘirul de date al mesajului
idNuIdentificatorul evenimentului pentru Last-Event-ID
retryNuÎntârzierea reconectării în ms

Exemplu de flux 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

EventSource API pe client

EventSource API — interfața încorporată a browserului pentru recepționarea SSE. Pentru a crea o conexiune, este suficient să apelați constructorul cu URL-ul endpoint-ului. EventSource stabilește automat conexiunea, gestionează reconectarea și parsează mesajele primite în evenimente JavaScript.

Evenimente EventSource: open (conexiune stabilită), message (mesaj primit fără specificarea event), error (eroare de conexiune). Pentru evenimente personalizate (event: custom) se poate folosi addEventListener cu numele evenimentului. EventSource trimite automat antetul Last-Event-ID la reconectare, permițând serverului să reia fluxul de la punctul întrerupt.

Conform documentației MDN (2025), EventSource suportă CORS și transmiterea credentialelor (withCredentials). Pentru transmiterea de anteturi personalizate sau corp de cerere, EventSource nu este potrivit — este necesară o implementare manuală prin fetch + ReadableStream. EventSource nu suportă date binare — doar text și JSON.

Cod client JavaScript

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

eventSource.addEventListener('open', () => {
    console.log('Conexiune SSE deschisă');
});

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

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

eventSource.addEventListener('error', (error) => {
    console.error('Eroare SSE:', error);
    // Reconectare automată a browserului
});

// Închide conexiunea
eventSource.close();

SSE vs WebSocket: comparație

SSE și WebSocket — tehnologii diferite pentru comunicare în timp real, fiecare cu punctele sale forte. WebSocket este potrivit pentru schimbul bidirecțional de date (chat-uri, jocuri, editare colaborativă), SSE — pentru fluxuri unidirecționale de la server la client (notificări, fluxuri de știri, tickere).

Diferența cheie — WebSocket necesită o cerere de upgrade de la HTTP/1.1 la protocolul WebSocket (ws://), care poate fi blocată de proxy-uri corporative. SSE funcționează pe HTTP obișnuit, trece prin orice proxy și nu necesită configurație specială a serverului. SSE este, de asemenea, mai simplu de implementat — serverul nu are nevoie de o bibliotecă suplimentară, este suficient să formateze corect răspunsul HTTP.

Conform datelor testelor comparative (2024), pe un singur proces server, SSE suportă cu 30–50% mai multe conexiuni decât WebSocket datorită unui protocol mai simplu. Totuși, latența SSE este mai mare (50–200 ms față de 10–50 ms pentru WebSocket) deoarece SSE utilizează HTTP chunked, nu un flux bidirecțional complet cu cadre binare.

CaracteristicăSSEWebSocket
DirecțieServer → clientBidirecțional
ProtocolHTTP (text/event-stream)ws:// / wss:// (RFC 6455)
Browsere97.5% (EventSource încorporat)97% (WebSocket încorporat)
DateDoar text / JSONText + binare (Blob, ArrayBuffer)
Gestionare proxyTrece prin orice proxyNecesită configurare proxy
ReconectareAutomată (browser)Implementare manuală
IstoricLast-Event-IDFără istoric încorporat

Cum se implementează SSE pe server

Implementarea SSE pe server nu necesită biblioteci — este suficient să setați anteturile HTTP corecte și să trimiteți datele în format text/event-stream. Să analizăm un exemplu în Node.js folosind modulul http încorporat. Serverul setează anteturile Content-Type și Cache-Control, apoi trimite mesaje la fiecare N secunde.

Conform MDN Web Docs (2025), anteturile obligatorii pentru SSE sunt: Content-Type: text/event-stream, Cache-Control: no-cache și Connection: keep-alive. Fără Cache-Control, browserul poate cache-ui fluxul SSE, ceea ce va duce la oprirea livrării. Connection: keep-alive indică explicit browserului să mențină conexiunea deschisă.

Cod server 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: {"timp": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
    }, 2000);

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

SSE în 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 în aplicații mobile

Utilizarea SSE în aplicațiile mobile este limitată de lipsa unei implementări native EventSource pentru iOS și Android. Pe platformele mobile, SSE este implementat prin biblioteci terțe: pe iOS — prin URLSession cu NSURLProtocol, pe Android — prin OkHttp cu suport SSE (okhttp-sse). Pentru React Native și Flutter sunt disponibile pachete care emulează EventSource.

Pe iOS implementarea nativă SSE este posibilă prin URLSessionDataDelegate. La primirea datelor în metoda urlSession(_:dataTask:didReceive:), aplicația acumulează buffer-ul și parsează manual formatul event-stream. Conform blogului de dezvoltare iOS (2024), consumul bateriei la SSE pe iOS este cu 40% mai mic decât la o conexiune WebSocket constantă, datorită absenței pachetelor heartbeat.

Pe Android OkHttp oferă clasa EventSource.Factory pentru abonarea la fluxuri SSE. Aplicațiile Android pot folosi SSE pentru notificări atunci când FCM nu este disponibil sau pentru sincronizarea datelor în fundal. SSE pe Android funcționează bine cu WorkManager pentru sarcini de fundal de lungă durată. Conform documentației OkHttp (2025), okhttp-sse suportă reconectarea automată cu un listener personalizat.

Întrebări frecvente

Cu ce se diferențiază SSE de WebSocket?

SSE — transmitere unidirecțională (server → client) prin HTTP, nu necesită biblioteci pe client. WebSocket — transmitere bidirecțională cu protocol binar. SSE este mai simplu de implementat, WebSocket este potrivit pentru sarcini unde clientul trimite și el date.

Suportă SSE date binare?

Nu, SSE transmite doar date text. Pentru date binare (imagini, audio) este necesară codificarea Base64, care mărește dimensiunea cu 33%. Pentru fluxuri binare este mai bine să folosiți WebSocket.

Cum gestionează SSE întreruperile conexiunii?

EventSource se reconectează automat la întrerupere. Timpul de întârziere este setat prin câmpul retry în flux (implicit 1000 ms). La reconectare, browserul trimite antetul Last-Event-ID, permițând serverului să reia fluxul de la punctul întrerupt.

Câte conexiuni SSE poate menține browserul?

Fiecare browser are o limită de conexiuni HTTP simultane cu un singur domeniu. Pentru HTTP/1.1 — 6–8 conexiuni per domeniu, pentru HTTP/2 — până la 100. SSE folosește o singură conexiune, deci nu apare concurență cu alte cereri.

Poate fi folosit SSE pentru chat?

SSE este potrivit doar pentru primirea mesajelor (intrări). Pentru trimiterea mesajelor (ieșiri) este necesară o cerere HTTP separată (POST). Pentru un chat complet este mai convenabil să folosiți WebSocket sau Socket.IO cu comunicare bidirecțională într-o singură conexiune.

Rezumat

  • SSE — standard de transmitere unidirecțională a datelor de la server la client printr-o conexiune HTTP obișnuită fără biblioteci suplimentare.
  • EventSource API — interfață browser încorporată, suportată de 97.5% din browserele moderne.
  • Protocol text simplu text/event-stream cu câmpurile event, data, id și retry.
  • Reconectare automată cu suport Last-Event-ID pentru reluarea fluxului de la punctul întrerupt.
  • Eficiență — SSE suportă mai multe conexiuni pe server (50 000+) comparativ cu WebSocket datorită unui protocol mai simplu.
  • Pe platforme mobile SSE este implementat prin OkHttp (Android) sau URLSession (iOS) cu parsare manuală a fluxului.
  • Pentru fluxuri unidirecționale (notificări, fluxuri, tickere) alegeți SSE, pentru comunicare bidirecțională — WebSocket sau Socket.IO.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și