Server-Sent Events in C#: Reaktives Web ohne WebSocket

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 "spricht" Ihre Website noch nicht in Echtzeit mit dem Benutzer?

\n\n

Stellen Sie sich vor: Sie öffnen einen Börsenterminal, und der Dollarkurs aktualisiert sich von selbst. Oder Sie gehen ins Admin-Panel und sehen, wie die Anzahl der registrierten Benutzer direkt vor Ihren Augen steigt. Oder ein Chat, in dem Nachrichten ohne ständige Seitenaktualisierungen eintreffen.

\n\n

Früher musste man dafür entweder WebSocket einsetzen (komplex, teuer, nicht immer nötig) oder Long Polling verwenden (ein Workaround, der den Telefonakku leert). Aber es gibt einen dritten Weg – Server-Sent Events in C#.

\n\n

Heute analysieren wir eine Technologie, die es dem Server ermöglicht, von sich aus auf den Client zuzugreifen und Daten zu übertragen. Ohne überflüssigen Code, ohne Tonnen von JavaScript, ohne Kopfschmerzen mit Proxy-Servern. Nur C#, nur Hardcore.

\n\n

Was sind Server-Sent Events (SSE) und warum ist es kein "Protokoll für Arme"?

\n\n

Server-Sent Events (oder SSE) ist ein HTML5-Standard, der es dem Server ermöglicht, dem Client Streaming-Daten über eine normale HTTP-Verbindung zu senden. Der Client abonniert Ereignisse, und der Server schreibt einfach in den Response.Body. Das war's.

\n\n

Der Hauptunterschied zu WebSocket: SSE ist ein unidirektionaler Kanal (Server → Client). Sie müssen keine Daten zurücksenden? Perfekt, SSE ist Ihre Wahl. Dabei:

\n\n
    \n
  • Funktioniert über normales HTTP/1.1 und HTTP/2
  • \n
  • Verbindet sich bei Unterbrechung automatisch neu (im Browser-EventSource integriert)
  • \n
  • Erfordert keine zusätzlichen Bibliotheken auf dem Client (außer standardmäßigem JavaScript)
  • \n
  • Funktioniert durch beliebige Proxys und Load Balancer (im Gegensatz zu WebSocket)
  • \n
\n\n

In der Praxis wird SSE C# verwendet für:

\n
    \n
  • Benachrichtigungsfeeds (Push-Benachrichtigungen direkt im Browser)
  • \n
  • Serverüberwachung (Dashboards mit Live-Metriken)
  • \n
  • Log-Übertragung (z. B. tail -f im Browser)
  • \n
  • Streaming von KI-Generierungen (schrittweise Ausgabe von ChatGPT-ähnlichen Modellen)
  • \n
\n\n

Wie SSE funktioniert: Ein Protokoll in einer Zeile

\n\n

Alles Geniale ist einfach. Der Server sendet dem Client einen Textstrom in einem speziellen Format:

\n\n
data: Hallo Welt!\\n\\n\ndata: {"message": "JSON funktioniert auch"}\\n\\n\nevent: customEvent\\n\ndata: Ereignis mit Name\\n\\n
\n\n

Jede Nachricht beginnt mit data:, endet mit zwei Zeilenumbrüchen. Sie können event: für einen benutzerdefinierten Ereignistyp, id: für eine Kennung und retry: für das Timeout der Wiederverbindung angeben.

\n\n

Der Client abonniert in JavaScript so:

\n\n
const source = new EventSource("/api/stream");\nsource.onmessage = (event) => {\n    console.log("Erhalten:", event.data);\n};\nsource.addEventListener("customEvent", (event) => {\n    console.log("Benutzerdefiniertes Ereignis:", event.data);\n});
\n\n

Und das funktioniert in allen modernen Browsern. Keine npm-Pakete, keine WebSocket-Polyfills.

\n\n

Server-Sent Events in C#: Implementierung in ASP.NET Core

\n\n

Lassen Sie uns endlich Code schreiben. Der einfachste Weg, SSE in C# zu organisieren, ist ein Endpunkt in ASP.NET Core, der die Antwort nicht abschließt, sondern in Teilen hineinschreibt.

\n\n

Basis-SSE-Endpunkt

\n\n
using Microsoft.AspNetCore.Mvc;\n\n[ApiController]\n[Route("api")]\npublic class StreamController : ControllerBase\n{\n    [HttpGet("stream")]\n    public async Task Get(CancellationToken cancellationToken)\n    {\n        Response.Headers.Append("Content-Type", "text/event-stream");\n        Response.Headers.Append("Cache-Control", "no-cache");\n        Response.Headers.Append("Connection", "keep-alive");\n\n        for (int i = 0; i < 10; i++)\n        {\n            if (cancellationToken.IsCancellationRequested)\n                break;\n\n            // SSE-Format: data: ... \\n\\n\n            await Response.WriteAsync($"data: Nachricht #{i}\\n\\n",                

Blogs

Buchempfehlungen