Server-Sent Events in C++: Echtzeit ohne Magie und überflüssige Bibliotheken

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum eine normale HTTP-Anfrage wie ein Brief per Post ist und SSE wie ein Telegramm in Echtzeit

\n\n

Stellen 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\n

Stellen 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\n

In 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\n

Wie funktionieren Server-Sent Events? Protokollanalyse

\n\n

SSE 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.

\n\n

Das Nachrichtenformat ist denkbar einfach:

\n\n
data: Dies ist der Ereignistext\\n\\n
\n\n

Jedes 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.

\n\n

Beispiel für einen vollständigen Stream:

\n\n
id: 42\nevent: new_message\ndata: {"user": "Vasily", "text": "Hallo!"}\n\nid: 43\nevent: ping\ndata: Server lebt\n\n
\n\n

Der Client (Browser oder eine beliebige Anwendung) verarbeitet diese Zeilen und generiert JavaScript-Ereignisse. Alles Geniale ist einfach.

\n\n

SSE vs WebSocket: Wann wählt man was?

\n\n

Viele 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
\n\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\n

Einen SSE-Server in C++ von Grund auf schreiben

\n\n

Fü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\n

Unser 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
\n\n

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                

Blogs

Buchempfehlungen