A real-time chat application built with ASP.NET Core and SignalR, designed for local-network use. Features broadcast messaging, private direct messages, multi-room support, typing indicators, and automatic reconnection — all with a polished dark-mode UI.
| Feature | Detail |
|---|---|
| Real-time messaging | WebSocket-based broadcast via SignalR |
| Private messages | Direct peer-to-peer messaging within a session |
| Multi-room support | Create or join any room by name at login |
| Typing indicators | Live per-user typing state broadcast to the room |
| Auto-reconnect | Exponential back-off reconnection with UI feedback |
| Morse code encoder | Encode / decode your message text before sending |
| Theme switcher | 9 Bootstrap themes + dark/light mode toggle |
| Docker support | Single-image deployment via docker-compose |
| Structured logging | Serilog with console sink for all hub events |
Browser (Vanilla JS + SignalR client)
│
│ WebSocket / Long-polling (auto-negotiated)
▼
ASP.NET Core 10 (MVC + SignalR Hub)
├── ChatHub — connection lifecycle, rooms (Groups), typing, messaging
├── HomeController — serves chat view with username + room context
├── LoginController — serves the login landing page
└── Serilog — structured console logging
Key design choices:
- Session-only messages — No database. Messages exist only for the duration of the browser session. This is intentional for a local-network environment where persistence is not required and simplicity is preferred.
- Server-side Groups — Rooms are implemented using SignalR's built-in
GroupsAPI. Messages are scoped to a group; the server never broadcasts to unintended clients. - Thread-safe state —
ConcurrentDictionaryis used for all shared connection state to handle concurrent hub invocations safely. - XSS prevention — All user-supplied strings rendered in the browser are escaped via
document.createTextNode, notinnerHTML.
- .NET 10 SDK
- Docker (optional, for containerised run)
git clone https://github.com/shawnfeds/SignalRChatApp.git
cd SignalRChatApp
dotnet runOpen your browser at https://localhost:7XXX (port shown in the console).
Enter your name and a room name, then click Join Chat.
Local network: other devices on the same network can connect using your machine's IP address and the app's port.
docker-compose up --buildApp will be available at http://localhost:8080.
- Join — Enter your name and a room (e.g.
General,Team-A). Any room name creates or joins that room. - Broadcast — Leave the recipient as Everyone in room and type your message.
- Private message — Select a specific user from the recipient dropdown (shown with 🔒).
- Morse code — Click the ℹ icon in the compose area to toggle Morse encoding/decoding of your message text before sending.
- Switch themes — Use the Theme menu in the header to apply one of 9 Bootstrap themes.
SignalRChatApp/
├── ChatHub.cs # SignalR hub — rooms, messaging, typing
├── Controllers/
│ ├── HomeController.cs # Chat page controller
│ └── LoginController.cs # Login page controller
├── Views/
│ ├── Home/Index.cshtml # 3-panel chat UI
│ ├── Login/Index.cshtml # Glassmorphism login card
│ └── Shared/_Layout.cshtml
├── wwwroot/
│ ├── css/site.css # Custom dark-mode design system
│ └── js/
│ ├── chat.js # SignalR client — reconnect, typing, rooms
│ ├── morseCode.js # Morse encode/decode
│ └── theme.js # Bootstrap theme switcher
├── Program.cs # App bootstrap + Serilog config
├── Dockerfile # Multi-stage .NET 10 build
└── docker-compose.yml
GitHub Actions runs on every push and pull request to main:
- ✅
dotnet restore - ✅
dotnet build --configuration Release - ✅
docker build(Dockerfile validation)
- JWT authentication (replace username query string)
- Message persistence with Entity Framework Core + SQLite
- Unit tests for
ChatHubwithMock<IHubCallerClients> - Integration tests via
WebApplicationFactory - Mobile-responsive sidebar toggle