Die unterschätzte Technik der Server-Sent Events (SSE)
(igorstechnoclub.com)Server-Sent Events (SSE) werden unterschätzt
- Die meisten Entwickler kennen WebSockets, aber SSE ist eine einfachere und oft übersehene Alternative.
- SSE richtet über HTTP einen unidirektionalen Kommunikationskanal vom Server zum Client ein.
- Anders als die bidirektionale Verbindung von WebSockets hält SSE eine offene HTTP-Verbindung für Updates vom Server zum Client aufrecht.
Warum SSE unterschätzt wird
- Die Popularität von WebSockets: Die Full-Duplex-Kommunikation von WebSockets überschattet den einfacheren Ansatz von SSE.
- Wahrgenommene Einschränkungen: Die unidirektionale Natur mag eingeschränkt wirken, ist für viele Anwendungsfälle aber ausreichend.
Zentrale Stärken von SSE
-
Einfache Implementierung
- Nutzt das standardisierte HTTP-Protokoll und beseitigt die Komplexität der Verwaltung von WebSocket-Verbindungen.
-
Infrastruktur-Kompatibilität
- Funktioniert nahtlos mit bestehender HTTP-Infrastruktur:
- Load Balancer
- Proxys
- Firewalls
- Standard-HTTP-Server
- Funktioniert nahtlos mit bestehender HTTP-Infrastruktur:
-
Ressourceneffizienz
- Geringerer Ressourcenverbrauch als WebSockets:
- unidirektionale Natur
- Nutzung standardisierter HTTP-Verbindungen
- keine permanente Socket-Wartung erforderlich
- Geringerer Ressourcenverbrauch als WebSockets:
-
Automatische Wiederverbindung
- Eingebaute Browser-Unterstützung:
- Umgang mit Verbindungsabbrüchen
- automatische Wiederverbindungsversuche
- belastbare Echtzeit-Erfahrung
- Eingebaute Browser-Unterstützung:
-
Klare Semantik
- Das unidirektionale Kommunikationsmuster sorgt für:
- klare Trennung der Zuständigkeiten
- intuitiven Datenfluss
- vereinfachte Anwendungslogik
- Das unidirektionale Kommunikationsmuster sorgt für:
Praktische Anwendungen
- Echtzeit-Newsfeeds und Social-Updates
- Aktienkurse und Finanzdaten
- Fortschrittsbalken und Job-Monitoring
- Streaming von Server-Logs
- Kollaboratives Bearbeiten (für Updates)
- Game-Leaderboards
- Systeme zur Standortverfolgung
Implementierungsbeispiel
Serverseite (Flask)
- Die Route
/streamverarbeitet die SSE-Verbindung. generate_random_data()erzeugt fortlaufend formatierte Events.- Der MIME-Typ
text/event-streamsignalisiert das SSE-Protokoll. stream_with_contexthält den Flask-Anwendungskontext aufrecht.
Client-Seite (JavaScript)
- Das Objekt
EventSourceverwaltet die SSE-Verbindung. - Der Handler
onmessageverarbeitet empfangene Events. onerrorbehandelt Verbindungsprobleme.- Der Browser übernimmt die automatische Wiederverbindung.
Einschränkungen und Überlegungen
-
Unidirektionale Kommunikation
- Nur vom Server zum Client möglich
- Kommunikation vom Client zum Server erfordert separate HTTP-Anfragen
-
Browser-Unterstützung
- In modernen Browsern gut unterstützt
- In älteren Browsern kann ein Polyfill nötig sein
-
Datenformat
- Unterstützt hauptsächlich textbasierte Daten
- Binärdaten müssen kodiert werden (z. B. Base64)
Best Practices
-
Fehlerbehandlung
- Verbindungsfehler mit
eventSource.onerrorbehandeln.
- Verbindungsfehler mit
-
Verbindungsmanagement
- Verbindung nach Abschluss bereinigen.
-
Wiederverbindungsstrategie
- Maximale Anzahl an Wiederholungen festlegen und Wiederverbindungslogik implementieren.
Praxisbeispiel: Die Implementierung von ChatGPT
- Moderne Large Language Models (LLMs) verwenden SSE, um Streaming-Antworten bereitzustellen.
- Wichtige Muster:
- Rückgabe des Headers
content-type: text/event-stream - Streaming von Datenblöcken, getrennt durch
\r\n\r\n
- Rückgabe des Headers
Fazit
- SSE bietet eine elegante Lösung für Echtzeit-Kommunikation zwischen Server und Client.
- Die Einfachheit, Effizienz und Integration in bestehende Infrastruktur machen es für viele Anwendungen zu einer geeigneten Wahl.
- WebSockets bleiben für bidirektionale Kommunikation nützlich, aber SSE ist stärker auf unidirektionale Datenstreaming-Szenarien fokussiert und dafür oft die passendere Lösung.
5 Kommentare
Ich habe SSE tatsächlich verwendet, als ich OpenAI über REST implementiert habe.
In Situationen, in denen unidirektionale Kommunikation nötig ist, werde ich die Technologie auf jeden Fall einsetzen.
Bei SSE erlebt man häufig, dass die Technik zwar nicht von Sicherheitsgeräten wie Web Application Firewalls oder intelligenten Sicherheitssystemen blockiert wird, Streaming auf Basis von Zeilenumbrüchen aber trotzdem nicht funktioniert. (On-Premises) wird die Antwort dazwischen vollständig entgegengenommen und dann auf einmal weitergeleitet.
Es ist wirklich schade, dass OpenAPI SSE nicht unterstützt.
In NAT-Umgebungen ist das wirklich eine sehr gute Methode, bidirektionale Kommunikation aufzubauen.
Hacker-News-Kommentare
Mercure ist ein offenes, auf SSE basierendes Protokoll und dient als Alternative zu WebSocket-basierten Lösungen. Mercure arbeitet rund um einen eigenständigen Hub, der dauerhafte SSE-Verbindungen mit Clients aufrechterhält, und bietet eine einfache HTTP-API, die sowohl Server-Apps als auch Clients nutzen können. Mercure ergänzt Funktionen wie einen JWT-basierten Authentifizierungsmechanismus, Abonnements mehrerer Topics über eine einzige Verbindung, Event-Aufzeichnung und automatische Zustandsanpassung bei Netzwerkproblemen
Ein großer Nachteil von SSE ist die Begrenzung der maximalen Anzahl an Verbindungen, wenn nicht HTTP/2 verwendet wird. Das kann wegen der niedrigen Browser-Limits problematisch sein, wenn mehrere Tabs geöffnet sind
In der CLI von Doppler wurde mit SSE eine Auto-Restart-Funktion implementiert. Über SSE werden Events vom Server empfangen, aktuelle Geheimnisse abgerufen und in den Applikationsprozess injiziert. Der Grund für die Wahl von SSE statt WebSockets war, keine zusätzlichen Abhängigkeiten in die Golang-Applikation zu holen. Um Probleme mit HTTP-Timeouts zu lösen, mussten gelegentlich "ping"-Events gesendet werden
Die unidirektionale Natur von SSE kann einschränkend wirken, ist in vielen Fällen aber ausreichend. Die wichtigsten Einschränkungen von SSE sind, dass es nur Text unterstützt, sowie die Browser-Verbindungsgrenzen unter HTTP/1.1. Mit HTTP/2 oder höher sind die Verbindungsgrenzen kein Problem mehr. Wenn Performance entscheidend ist, kann man mit
fetchundReadableStreameine flexiblere Lösung mit weniger Overhead wählenWegen der Einfachheit von SSE verwenden viele Entwickler keine saubere Implementierung und parsen Daten-Chunks stattdessen mit regulären Ausdrücken. Das kann problematisch sein, weil SSE Kommentare im Stream unterstützt
Data-star.dev ist eine Frontend-Bibliothek mit Fokus auf das Streamen von Hypermedia-Antworten über SSE. Sie wurde mit Go und NATS als Backend-Technologien entwickelt und ist mit allen SSE-Implementierungen kompatibel
SSE ist nicht unterbewertet. Tatsächlich wird es bei Open AI für Streaming-Completions verwendet. Die Implementierung von SSE in einer ReactJS-Codebasis war schwierig, und da Axios es damals nicht unterstützte, musste natives
fetchverwendet werdenAls SSE in einem Webprojekt implementiert wurde, funktionierte die Website nicht mehr, sobald mehr als 6 Tabs geöffnet waren. Firefox zählt SSE-Verbindungen zum Host-Limit von maximal 6 Verbindungen, wodurch zusätzliche Requests blockiert werden
SSE ist unterbewertet, wenn es gut funktioniert. In einem aktuellen Projekt gibt es jedoch Schwierigkeiten mit der Authentifizierung und mit Keep-Alive-Problemen in Tunneln. Das ist kein Problem des Protokolls selbst, aber eine Lösung zu finden ist schwierig