Vor drei Monaten hat mir ein Fertigungsbetrieb mit 80 Mitarbeitenden gezeigt, was sein Entwickler über das Wochenende gebaut hatte: ein Live-Dashboard für Maschinenstatus-Meldungen, vollständig über WebSockets. Sah gut aus. Bis ich gefragt habe, welche Version von IIS läuft, und ob der vorgelagerte Reverse Proxy konfiguriert ist, dauerhafte Verbindungen durchzulassen. Schweigen. Dann: „Das Dashboard funktioniert nur, wenn man die Seite alle 30 Sekunden manuell neu lädt."
Das ist kein Einzelfall. Das ist Mittelstandsrealität. Nicht weil die Leute schlecht sind – sondern weil technische Artikel, so gut sie auch sein mögen, in einer Welt geschrieben werden, die mit der Produktivumgebung deines Kunden wenig gemein hat.
Was Khalid zeigt
Khalid Abuhakmeh, Developer Advocate bei JetBrains, hat einen sauberen, handwerklich guten Artikel geschrieben. Die Kernaussage: Ab .NET 10 kannst du in ASP.NET Core Minimal APIs direkt TypedResults.ServerSentEvents() zurückgeben. Du gibst dem Endpoint ein IAsyncEnumerable<string>, setzt einen Event-Typ – fertig. Der Client subscribt via new EventSource('/orders'), und die Nachrichten fließen unidirektional vom Server zum Browser.
Das Beispiel ist konkret: ein FoodService mit INotifyPropertyChanged, ein BackgroundService, der alle Sekunde eine neue Emoji-Bestellung generiert, und ein minimalisches HTML-Frontend. Zwei Browser-Tabs öffnen, beide zeigen synchron dieselben Food-Emojis. Technisch korrekt, klar erklärt, gut lesbar.
Der Vergleich mit SignalR/WebSockets ist fair: SSE ist leichter, läuft über normales HTTP, ist für unidirektionale Szenarien ausreichend. Für eine Live-News-Feed oder ein Notifications-Banner brauchst du keine bidirektionale Verbindung.
Wie das im Mittelstand wirklich landet
Lass mich direkt sein: Khalids Artikel beschreibt das Ideal. Das Ideal ist nicht falsch. Aber zwischen „funktioniert im Demo-Projekt" und „läuft stabil in einer KMU-Infrastruktur" liegen mindestens vier Probleme, die im Artikel nicht vorkommen.
Problem 1: Kaum jemand ist auf .NET 10.
Stand heute läuft bei meinen Mandanten (30 bis 300 Mitarbeitende, meist Produktion, Handel, Dienstleistung) der .NET-Stack mehrheitlich auf .NET 6 LTS oder .NET 8 LTS. .NET 10 erscheint im November 2026. Wer jetzt ein neues Feature plant, plant es für eine Plattform, die sein Team in 6 bis 18 Monaten produktiv nutzen wird – wenn überhaupt. Das ist keine Kritik an Khalid, der über die Zukunft schreibt. Aber du solltest wissen: TypedResults.ServerSentEvents ist kein Feature, das du nächste Woche in deinem bestehenden Projekt einschalten kannst.
Problem 2: Der Proxy schneidet die Verbindung.
SSE lebt davon, dass eine HTTP-Verbindung offen bleibt – Sekunden, Minuten, Stunden. In jedem Mittelstandsbetrieb sitzt davor mindestens einer dieser Kandidaten: IIS als Reverse Proxy, ein nginx ohne angepasste proxy_read_timeout, ein Azure Application Gateway mit Default-Timeouts, oder ein Loadbalancer vom Hosting-Anbieter, der nach 60 Sekunden Inaktivität trennt. Ohne explizite Konfiguration bekommst du disconnects, die der Client nicht sauber erkennt – und dein „Live"-Dashboard ist wieder manuelles Reload.
Konkret: Bei nginx brauchst du mindestens proxy_buffering off, proxy_read_timeout 3600s, und X-Accel-Buffering: no im Response-Header. Das steht nicht im Artikel. Das steht auch in keinem Getting-Started-Tutorial. Das lernst du, wenn der Kunde dich um 14 Uhr anruft.
Problem 3: Das In-Memory-Singleton skaliert nicht.
Khalids FoodService ist ein AddSingleton. Solange du einen einzigen Server hast, funktioniert das. Sobald dein Kunde zwei Instanzen fährt – ob über Azure App Service Auto-Scale, ob über eine simple zweite VM hinter dem Loadbalancer – haben beide Instanzen ihren eigenen Singleton. Request A landet auf Server 1, Request B auf Server 2. Die Clients sehen unterschiedliche Events. Das Beispiel im Artikel ist didaktisch richtig, aber produktionstauglich nur für Single-Instance-Deployments. Für alles andere brauchst du einen externen Pub/Sub-Bus: Redis, Azure Service Bus, oder – ganz pragmatisch – einen Datenbank-Polling-Ansatz mit kurzen Intervallen, der auf jedem Setup läuft.
Problem 4: Authentifizierung fehlt vollständig.
Der /orders-Endpoint im Beispiel ist anonym. In der Praxis willst du SSE-Endpoints fast immer absichern – Dashboards zeigen interne Daten, Notification-Feeds sind benutzerspezifisch. Das funktioniert mit Bearer-Token über EventSource nicht out-of-the-box, weil der Browser-native EventSource-API keine Custom Headers erlaubt. Du musst entweder auf Cookie-Auth umsteigen, ein Token als Query-Parameter übergeben (hat Sicherheitsimplikationen), oder eine polyfill-Bibliothek einsetzen. Für ein KMU, das „einfach ein Live-Update auf die interne Dashboard-Seite" will, ist das oft der Punkt, an dem der einfache Ansatz komplex wird.
Was ich trotzdem empfehle
SSE ist das richtige Werkzeug für eine klar definierte Menge von Problemen. Wenn du eine einseitige Live-Anzeige brauchst – Produktionsstatus, Auftragsstatus, Echtzeit-Log-Output in einem internen Tool – ist SSE besser als Polling (weniger Last, kein Delay) und besser als WebSockets (einfacher, keine spezielle Infrastruktur für Bidirektionalität).
Mein konkreter Rat für den .NET-Mittelstand heute:
-
Wenn du .NET 8 hast: Implementier SSE mit manuellem Response-Streaming. Es braucht 30 Zeilen mehr als Khalids
.NET 10-Version, aber es funktioniert heute. Es gibt stabile NuGet-Pakete, die das abstrahieren. -
Wenn du .NET 10 planst: Nimm Khalids Artikel als Startpunkt – aber ergänze ihn um die Proxy-Konfiguration, und entscheide bewusst, ob dein Deployment Single-Instance bleibt oder nicht.
-
Wenn Multi-Instance: Plan von Anfang an Redis als Backbone. Ein
IConnectionMultiplexerals Singleton, Pub/Sub-Channel stattINotifyPropertyChanged. Das sind zwei zusätzliche Tage Arbeit, aber du sparst dir drei Wochen Fehlersuche. -
Für alles andere: Bevor du SSE einführst, frag deinen Hosting-Anbieter explizit, ob lang laufende HTTP-Verbindungen unterstützt werden und welche Timeouts gelten. Das ist eine E-Mail, kein Ticket – aber sie spart dir zwei Wochen.
Die Technologie ist gut. Der Artikel ist gut. Die Lücke ist der Weg von „funktioniert lokal" zu „läuft stabil beim Kunden".
Der vollständige Original-Beitrag von Khalid Abuhakmeh: Server-Sent Events in ASP.NET Core and .NET 10
Du willst wissen, ob SSE für dein konkretes Szenario das Richtige ist – oder ob Polling, WebSockets oder gar kein Real-Time der pragmatischere Weg wäre? Dann lass uns das in 30 Minuten klären.
— Bernhard