💬
Real-Time Chat Application
Advanced Project — SignalR, Caching, Presence Tracking
🧠 Project Overview
Build a real-time chat application with SignalR. Practice typed hubs, group management, message persistence, user presence tracking, and typing indicators.
🎯 Requirements
- • Multiple chat rooms with join/leave functionality
- • Real-time messaging with SignalR typed hub
- • Message history with caching
- • Online user presence tracking
- • Typing indicators
- • JWT authentication for hub connections
Step 1: Typed SignalR Hub
ChatHub with Groups & Presence
Typed hub with rooms, typing indicators, and connection tracking.
C#
// Hubs/ChatHub.cs
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.Authorization;
[Authorize]
public class ChatHub : Hub<IChatClient>
{
private readonly IChatService _chatService;
private static readonly ConnectionManager _connections = new();
public ChatHub(IChatService chatService) => _chatService = chatService;
public async Task JoinRoom(string roomName)
{
await Groups.AddToGroupAsync(Context.ConnectionId, roomName);
_connections.Add(Conte
...Step 2: Chat Service
ChatService — Persistence & Caching
Save messages to database and cache recent history.
C#
// Services/ChatService.cs
public class ChatService : IChatService
{
private readonly AppDbContext _db;
private readonly IMemoryCache _cache;
public ChatService(AppDbContext db, IMemoryCache cache)
{
_db = db;
_cache = cache;
}
public async Task<ChatMessage> SaveMessage(
string userName, string room, string content)
{
var message = new ChatMessage
{
Id = Guid.NewGuid(),
UserName = userName,
...Step 3: Connection Manager
Thread-Safe Connection Manager
Track online users per room with ConcurrentDictionary.
C#
// Infrastructure/ConnectionManager.cs
using System.Collections.Concurrent;
public class ConnectionManager
{
private readonly ConcurrentDictionary<string, ConnectionInfo> _connections = new();
public void Add(string connectionId, string userName, string room)
{
_connections.TryAdd(connectionId,
new ConnectionInfo(userName, room));
}
public ConnectionInfo? Remove(string connectionId)
{
_connections.TryRemove(connectionId, out var info);
...Challenge Complete Checklist
- ☐ Multiple users can chat in real-time
- ☐ Room switching works with history loading
- ☐ Typing indicators show for other users
- ☐ Online presence updates when users join/leave
- ☐ Messages persist across page refreshes