Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Real-time Options: Polling, Long Polling, Server-Sent Events, WebSocket and SignalR — Which One When?
Use SSE for one-way notifications, WebSocket or SignalR for two-way low latency, and polling for rarely changing data. We build the same order status feature five ways and measure latency, request count and memory per connection; plus a decision table, where WebTransport stands, and why not everything should be real-time.
Raw WebSockets in ASP.NET Core: UseWebSockets, the Receive Loop, the Close Handshake and an Angular Client
With raw WebSockets you must accumulate a message until EndOfMessage with a size limit, write to the socket from a single loop and check Origin yourself. The receive loop, the close handshake, KeepAliveTimeout, a Channel-based send queue, a connection registry, the compression risk, and reconnecting with backoff in Angular using RxJS webSocket().
Server-Sent Events in Depth: TypedResults.ServerSentEvents, Resuming with Last-Event-ID and Proxy Pitfalls
To make up for missed SSE events, give every event an EventId, resend everything after the Last-Event-ID header and send a heartbeat as soon as the client connects. SseItem<T>, retry, CancellationToken, the Nginx gzip and timeout traps, HTTP/1.1's 6-connection limit, wrapping EventSource in an Observable in Angular, and reading with fetch when you need headers.
Getting Started with ASP.NET Core SignalR: Hubs, Strongly Typed Hubs and Connecting from Angular with @microsoft/signalr
A SignalR hub is a transient handler created for every call; it holds no state and reports user-facing errors with HubException. AddSignalR and MapHub, type-safe calls with Hub<IClient>, transport negotiation, encapsulating the HubConnection in an Angular service that publishes signals, and AllowCredentials with an explicit origin list.
Users, Groups and Connection Lifecycle in SignalR: Sending Messages from Anywhere with IHubContext
Clients.User reaches all of a user's tabs, while group membership belongs to the connection and is lost on reconnect. IUserIdProvider, Caller/Others/OthersInGroup, the unexpected ordering of OnConnectedAsync and OnDisconnectedAsync, counter-based presence in Redis, and sending notifications from an endpoint, a BackgroundService and a consumer with IHubContext.
Authentication, Authorization and Security in SignalR: JWT, the access_token Query String and Hub Method Policies
SignalR authenticates a user once, when connecting; by default the connection stays open even after the token expires or a role changes. access_token via OnMessageReceived, tokens leaking into logs, accessTokenFactory, hub and method policies, resource-based checks with HubInvocationContext, rate limiting with IHubFilter, message size, Origin, and CloseOnAuthenticationExpiration.
Resilience in SignalR: Automatic Reconnect, Stateful Reconnect, Streaming and MessagePack
Stateful reconnect prevents message loss only on short drops that recover instantly; an outage of a few seconds still means a new connection and lost messages. A retry policy with jitter, rebuilding groups in onreconnected, server and client streaming with IAsyncEnumerable, cancellation, MessagePack's byte savings and its PascalCase and date traps, and limits for slow clients.
Scaling Out and Running SignalR in Production: Sticky Sessions, Redis Backplane, Azure SignalR Service and Monitoring
SignalR on multiple servers needs two things: sticky sessions that keep negotiate and the connection on the same server, and a backplane that carries messages between servers. Real error messages with Nginx, the skipNegotiation exception, the Redis backplane and its channel prefix, messages lost during a Redis outage, Azure SignalR Service, and SignalR metrics and tracing.
What's New in Real-time from .NET 8 to .NET 11: Stateful Reconnect, Native AOT, SSE and SignalR Authentication Refresh
.NET 8 brought stateful reconnect, .NET 9 polymorphic hub parameters, an ActivitySource and Native AOT for SignalR, .NET 10 TypedResults.ServerSentEvents, and .NET 11 adds authentication refresh that renews the token without dropping the connection. A 28 MB vs 82 MB AOT measurement, the strongly typed hub AOT warning, cancellable hub calls, SSE in OpenAPI 3.2 and legacy ASP.NET SignalR.