Prototype of a real-time messaging backend with ASP.NET Core SignalR that scales horizontally: several server instances share messages through a Redis backplane, so a client connected to instance A receives messages sent by a client connected to instance B.
Built to explore how to run SignalR behind multiple nodes before using it for real-time features (chat, notifications, game events).
| Project | What it is |
|---|---|
ServerSide |
ASP.NET Core (.NET 10) server: MessageHub for chat, NotificationHub plus REST endpoint for push notifications, Swagger UI |
ClientLib |
.NET Standard 2.0 client library: strongly typed send/receive helpers on top of HubConnection |
ClientSide |
Console client that connects to a server and chats |
Common |
Shared DTOs and hub/method name constants |
Key choices:
- Redis backplane (
AddStackExchangeRedis) to fan out messages across instances. - MessagePack protocol instead of JSON, for smaller payloads.
- Strongly typed messages on the client (
connection.MessageHandler<T>(...)), with shared constants instead of magic strings. - Server-initiated notifications through
IHubContext, triggered by a REST call (POST /notification/global).
Two server instances plus Redis:
docker compose up --build- Instance 1: http://localhost:90 (Swagger at
/swagger) - Instance 2: http://localhost:95
Then start two console clients, one per instance, and send a message from one: it arrives on the other.
dotnet run --project ClientSide
# enter http://localhost:90 for the first client, http://localhost:95 for the secondThis is a learning prototype, not a finished product.
Done
- Global chat across instances
- Global push notifications from a REST endpoint
- Strongly typed client handlers
Not done yet
- Channels: the server already sends to SignalR groups, but clients can't join or leave a channel yet
- Private messages delivered only to the recipient (today they are broadcast)
- Authentication and authorization
- Tests