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 (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.
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.
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 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âmp | Obligatoriu | Scop |
|---|---|---|
| event | Nu | Tipul evenimentului (implicit message) |
| data | Da | Șirul de date al mesajului |
| id | Nu | Identificatorul evenimentului pentru Last-Event-ID |
| retry | Nu | Întârzierea reconectării în ms |
: 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 — 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.
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 ș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ă | SSE | WebSocket |
|---|---|---|
| Direcție | Server → client | Bidirecțional |
| Protocol | HTTP (text/event-stream) | ws:// / wss:// (RFC 6455) |
| Browsere | 97.5% (EventSource încorporat) | 97% (WebSocket încorporat) |
| Date | Doar text / JSON | Text + binare (Blob, ArrayBuffer) |
| Gestionare proxy | Trece prin orice proxy | Necesită configurare proxy |
| Reconectare | Automată (browser) | Implementare manuală |
| Istoric | Last-Event-ID | Fără istoric încorporat |
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ă.
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);
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')
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
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.
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.
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.
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.
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
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.
Citiți și