SSE (Server-Sent Events) — W3C-standaard waarmee de server via een enkele HTTP-verbinding in eenrichtingsmodus gegevens naar de client kan streamen. In tegenstelling tot WebSocket werkt SSE over gewone HTTP en vereist het geen speciaal protocol of bibliotheek aan de clientzijde. Volgens de W3C HTML Living Standard (2025) specificatie wordt EventSource API ondersteund in alle moderne browsers, waaronder Chrome, Firefox, Safari en Edge.
Belangrijkste punten
SSE (Server-Sent Events) — technologie waarmee een webserver op elk moment na het tot stand brengen van de verbinding gegevens naar de client kan sturen. Het is gestandaardiseerd door WHATWG als onderdeel van de HTML Living Standard en gebruikt het MIME-type text/event-stream. SSE ondersteunt het verzenden van tekstgegevens met de mogelijkheid om een bericht-ID, gebeurtenistype en herverbindingsvertraging op te geven.
In tegenstelling tot WebSocket, dat een bidirectioneel protocol en een upgrade-verzoek vereist, werkt SSE over gewone HTTP. De server stelt de header Content-Type: text/event-stream in, stuurt gegevens in delen en houdt de verbinding open. De client ontvangt gegevens via de browser-EventSource API, die automatisch de stream parsed en gebeurtenissen genereert.
Volgens CanIUse (2025) wordt EventSource API wereldwijd in 97,5% van de browsers ondersteund. Het wordt niet ondersteund in Internet Explorer en sommige mobiele browsers (Samsung Internet tot versie 7.0). Voor deze gevallen zijn er polyfills die EventSource emuleren via XHR streaming. SSE werkt niet met HTTP/1.1 pipelining, maar is volledig compatibel met HTTP/2 server push.
SSE werd in 2009 voorgesteld als onderdeel van de HTML5-specificatie onder de naam Server-Sent DOM Events. De eerste implementatie verscheen in Opera 9.0, daarna in Firefox 6.0 (2011), Chrome 9.0 (2011) en Safari 5.0 (2010). In 2015 werd de specificatie afgesplitst naar een aparte sectie van de HTML Living Standard. Ondanks een decennium aan geschiedenis blijft SSE minder populair dan WebSocket vanwege zijn eenrichtingsaard.
Het werkingsmechanisme van SSE is als volgt: de client maakt een EventSource-instantie met de URL van het serverendpoint. De browser stuurt een GET-verzoek met de header Accept: text/event-stream. De server antwoordt met status 200 OK en de header Content-Type: text/event-stream, waarna hij begint met het verzenden van gegevens in event-stream-formaat. De verbinding blijft open totdat de server een terminatiesignaal stuurt of de client close() aanroept.
Aan serverzijde worden gegevens in delen verzonden (chunked transfer encoding). Elk gegevensblok is een tekstbericht bestaande uit veldregels (event, data, id, retry). De server kan op elk moment berichten sturen, wat SSE ideaal maakt voor meldingen en statusupdates. De verbinding vereist geen constante heartbeat-pakketuitwisseling (zoals WebSocket), hoewel het retry-veld de frequentie van herverbinding regelt.
Volgens prestatietests (2024) biedt SSE een doorvoer van maximaal 10.000 berichten per seconde per verbinding bij een berichtgrootte van 256 bytes. Aan serverzijde verbruikt elke SSE-verbinding ongeveer 5–10 KB geheugen, waardoor een enkele server 50.000+ gelijktijdige verbindingen kan ondersteunen met 1 GB RAM. Dit is aanzienlijk minder dan WebSocket vanwege het ontbreken van een binair protocol.
Text/event-stream formaat — een eenvoudig tekstprotocol waarbij elk bericht bestaat uit benoemde velden gescheiden door nieuwe regeltekens. Elk veld heeft het formaat „Veldnaam: waarde”. Berichten worden gescheiden door twee nieuwe regeltekens ( ).
Ondersteunde velden: event (gebeurtenistype, standaard message), data (gegevensreeks, kan meerregelig zijn), id (laatste gebeurtenis-ID, opgeslagen in Last-Event-ID), retry (herverbindingstijd in milliseconden). Opmerkingen beginnen met een dubbele punt (:) en worden genegeerd door de parser, maar kunnen worden gebruikt voor heartbeat.
| Veld | Verplicht | Doel |
|---|---|---|
| event | Nee | Gebeurtenistype (standaard message) |
| data | Ja | Gegevensreeks van het bericht |
| id | Nee | Gebeurtenis-ID voor Last-Event-ID |
| retry | Nee | Herverbindingsvertraging in 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 — de ingebouwde browserinterface voor het ontvangen van SSE. Om een verbinding te maken volstaat het om de constructor aan te roepen met de URL van het endpoint. EventSource brengt automatisch de verbinding tot stand, beheert herverbinding en parsed inkomende berichten naar JavaScript-gebeurtenissen.
EventSource-gebeurtenissen: open (verbinding tot stand gebracht), message (bericht ontvangen zonder opgave van event), error (verbindingsfout). Voor aangepaste gebeurtenissen (event: custom) kan addEventListener met de gebeurtenisnaam worden gebruikt. EventSource stuurt automatisch de header Last-Event-ID bij herverbinding, waardoor de server de stroom kan hervatten vanaf het onderbroken punt.
Volgens MDN-documentatie (2025) ondersteunt EventSource CORS en het verzenden van credentials (withCredentials). Voor het verzenden van aangepaste headers of verzoekbody is EventSource niet geschikt — handmatige implementatie via fetch + ReadableStream is vereist. EventSource ondersteunt geen binaire gegevens — alleen tekst en JSON.
const eventSource = new EventSource('/api/events/stream');
eventSource.addEventListener('open', () => {
console.log('SSE-verbinding geopend');
});
eventSource.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Ontvangen:', data);
renderUpdate(data);
});
eventSource.addEventListener('notification', (event) => {
const notification = JSON.parse(event.data);
showNotification(notification.text);
});
eventSource.addEventListener('error', (error) => {
console.error('SSE-fout:', error);
// Automatische browser-herverbinding
});
// Verbinding sluiten
eventSource.close();
SSE en WebSocket — verschillende technologieën voor real-time communicatie, elk met hun eigen sterke punten. WebSocket is geschikt voor bidirectionele gegevensuitwisseling (chats, games, gezamenlijk bewerken), SSE voor eenrichtingsstromen van server naar client (meldingen, nieuwsfeeds, tickers).
Het belangrijkste verschil — WebSocket vereist een upgrade-verzoek van HTTP/1.1 naar het WebSocket-protocol (ws://), wat door bedrijfsproxy's kan worden geblokkeerd. SSE werkt over gewone HTTP, gaat door alle proxy's heen en vereist geen speciale serverconfiguratie. SSE is ook eenvoudiger te implementeren — de server heeft geen extra bibliotheek nodig, het volstaat om het HTTP-antwoord correct te formatteren.
Volgens vergelijkende tests (2024) ondersteunt SSE op één serverproces 30–50% meer verbindingen dan WebSocket vanwege het eenvoudigere protocol. De latentie van SSE is echter hoger (50–200 ms versus 10–50 ms voor WebSocket) omdat SSE chunked HTTP gebruikt, geen volledig bidirectionele stroom met binaire frames.
| Kenmerk | SSE | WebSocket |
|---|---|---|
| Richting | Server → client | Bidirectioneel |
| Protocol | HTTP (text/event-stream) | ws:// / wss:// (RFC 6455) |
| Browsers | 97,5% (ingebouwde EventSource) | 97% (ingebouwde WebSocket) |
| Gegevens | Alleen tekst / JSON | Tekst + binair (Blob, ArrayBuffer) |
| Proxy-verwerking | Gaat door alle proxy's | Vereist proxy-configuratie |
| Herverbinding | Automatisch (browser) | Handmatige implementatie |
| Geschiedenis | Last-Event-ID | Geen ingebouwde geschiedenis |
SSE implementeren op de server vereist geen bibliotheken — het volstaat om de juiste HTTP-headers in te stellen en gegevens te verzenden in text/event-stream formaat. Laten we een voorbeeld bekijken in Node.js met behulp van de ingebouwde http-module. De server stelt de headers Content-Type en Cache-Control in en stuurt vervolgens elke N seconden berichten.
Volgens MDN Web Docs (2025) zijn de verplichte headers voor SSE: Content-Type: text/event-stream, Cache-Control: no-cache en Connection: keep-alive. Zonder Cache-Control kan de browser de SSE-stream cachen, wat leidt tot het stoppen van de levering. Connection: keep-alive geeft de browser expliciet aan de verbinding open te houden.
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: {"tijd": "${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')
Gebruik van SSE in mobiele apps wordt beperkt door het ontbreken van een native EventSource-implementatie voor iOS en Android. Op mobiele platforms wordt SSE geïmplementeerd via externe bibliotheken: op iOS via URLSession met NSURLProtocol, op Android via OkHttp met SSE-ondersteuning (okhttp-sse). Voor React Native en Flutter zijn pakketten beschikbaar die EventSource emuleren.
Op iOS is native SSE-implementatie mogelijk via URLSessionDataDelegate. Bij het ontvangen van gegevens in de methode urlSession(_:dataTask:didReceive:) verzamelt de app een buffer en parsed handmatig het event-stream-formaat. Volgens iOS-ontwikkelblog (2024) is het batterijverbruik bij SSE op iOS 40% lager dan bij een constante WebSocket-verbinding, vanwege het ontbreken van heartbeat-pakketten.
Op Android biedt OkHttp de klasse EventSource.Factory voor het abonneren op SSE-streams. Android-apps kunnen SSE gebruiken voor meldingen wanneer FCM niet beschikbaar is of voor gegevenssynchronisatie op de achtergrond. SSE op Android werkt goed met WorkManager voor langdurige achtergrondtaken. Volgens OkHttp-documentatie (2025) ondersteunt okhttp-sse automatische herverbinding met een aangepaste listener.
Veelgestelde vragen
SSE — eenrichtingsverzending (server → client) via HTTP, vereist geen bibliotheken aan clientzijde. WebSocket — bidirectionele verzending met binair protocol. SSE is eenvoudiger te implementeren, WebSocket is geschikt voor taken waarbij de client ook gegevens verzendt.
Nee, SSE verzendt alleen tekstgegevens. Voor binaire gegevens (afbeeldingen, audio) is Base64-codering vereist, wat de grootte met 33% verhoogt. Voor binaire streams kun je beter WebSocket gebruiken.
EventSource maakt automatisch opnieuw verbinding bij onderbreking. De vertragingstijd wordt ingesteld via het retry-veld in de stream (standaard 1000 ms). Bij herverbinding stuurt de browser de header Last-Event-ID, waardoor de server de stroom kan hervatten vanaf het onderbroken punt.
Elke browser heeft een limiet voor het aantal gelijktijdige HTTP-verbindingen met één domein. Voor HTTP/1.1 — 6–8 verbindingen per domein, voor HTTP/2 — tot 100. SSE gebruikt één verbinding, dus er is geen concurrentie met andere verzoeken.
SSE is alleen geschikt voor het ontvangen van berichten (inkomend). Voor het verzenden van berichten (uitgaand) is een apart HTTP-verzoek (POST) nodig. Voor een volledige chat is het handiger om WebSocket of Socket.IO met bidirectionele communicatie in één verbinding te gebruiken.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook