Warum eine normale HTTP-Anfrage wie ein Brief per Post ist und SSE wie ein Telegramm in Echtzeit
\n\nStellen Sie sich vor: Sie warten auf eine Benachrichtigung über einen neuen Kommentar auf einer Website. Sie aktualisieren die Seite alle 5 Sekunden. Der Server gibt jedes Mal einen Haufen HTML, CSS, Bilder zurück – und erst ganz unten sehen Sie: „Keine neuen Kommentare“. Kommt Ihnen bekannt vor? Das nennt man Polling. Es funktioniert, aber es frisst Traffic und belastet den Server.
\n\nStellen Sie sich nun ein anderes Szenario vor: Sie öffnen die Seite, und nach einer Sekunde erscheint darauf die Nachricht: „Vasily hat einen Kommentar hinterlassen: „Toller Artikel!““. Ohne Neuladen, ohne unnötige Anfragen. Der Server „schiebt“ Ihnen die Daten selbst zu. Das sind Server-Sent Events (SSE) – eine Technologie, die es dem Server ermöglicht, dem Client einen Ereignisstrom über eine normale HTTP-Verbindung zu senden.
\n\nIn diesem Artikel werden wir untersuchen, wie man SSE in reinem C++ ohne den Einsatz schwerer Frameworks implementiert. Sie erfahren, warum Server-Sent Events in C++ eine hervorragende Wahl für Monitoring, Börsenkurse, Chat-Benachrichtigungen und alle Aufgaben ist, bei denen eine unidirektionale Datenübertragung in Echtzeit erforderlich ist.
\n\nWie funktionieren Server-Sent Events? Protokollanalyse
\n\nSSE ist Teil der HTML5-Spezifikation. Der Client öffnet eine normale HTTP-Verbindung und teilt dem Server mit: „Ich bin bereit, Ereignisse zu empfangen“. Der Server schließt die Verbindung daraufhin nicht, sondern beginnt, Daten in einem speziellen Format text/event-stream zu senden.
Das Nachrichtenformat ist denkbar einfach:
\n\ndata: Dies ist der Ereignistext\\n\\n\n\nJedes Ereignis beginnt mit data: und endet mit einem doppelten Zeilenumbruch. Sie können id: zur Identifikation, event: für den Ereignistyp und retry: zur Angabe der Wiederverbindungszeit in Millisekunden hinzufügen.
Beispiel für einen vollständigen Stream:
\n\nid: 42\nevent: new_message\ndata: {"user": "Vasily", "text": "Hallo!"}\n\nid: 43\nevent: ping\ndata: Server lebt\n\n\n\nDer Client (Browser oder eine beliebige Anwendung) verarbeitet diese Zeilen und generiert JavaScript-Ereignisse. Alles Geniale ist einfach.
\n\nSSE vs WebSocket: Wann wählt man was?
\n\nViele denken bei Echtzeit sofort an WebSocket. Vergleichen wir:
\n\n- \n
- WebSocket – bidirektionale Kommunikation. Client und Server können den Austausch initiieren. Erfordert ein separates Protokoll (ws://), muss Proxys passieren, wird oft von Unternehmens-Firewalls blockiert. \n
- SSE – unidirektionale Kommunikation (Server → Client). Funktioniert über normales HTTP. Verbindet sich bei Unterbrechung automatisch neu. Passiert problemlos alle Proxys. \n
Wenn Ihre Aufgabe darin besteht, Benachrichtigungen an den Client zu senden, ohne auf Befehle von ihm zu warten, sind Server-Sent Events in C++ eine elegante und einfache Lösung. Sie müssen keine schweren Bibliotheken mitbringen oder komplexe Handler schreiben.
\n\nEinen SSE-Server in C++ von Grund auf schreiben
\n\nFür die Implementierung benötigen wir ein Minimum: Sockets und HTTP-Handling. In realen Projekten verwendet man Boost.Beast oder libmicrohttpd, aber um das Prinzip zu verstehen, schreiben wir einen einfachen Server in reinem C++ mit POSIX-Sockets.
\n\nUnser Server wird:
\n- \n
- Eine HTTP-Anfrage vom Client entgegennehmen \n
- Erkennen, dass der Client SSE möchte (anhand des Headers
Accept: text/event-stream) - Alle 2 Sekunden einen Ereignisstrom mit der aktuellen Uhrzeit senden
Schritt 1: Socket erstellen und Port abhören
\n\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <sys/socket.h>\n#include <thread>\n#include <chrono>\n#include <sstream>\n\nvoid handle_client(int client_socket) {\n // Puffer für die Anfrage\n char buffer[4096] = {0};\n read(client_socket, buffer, 4096);\n \n // Prüfen, ob es ein GET ist