Why education products need real-time more than polling
Learners miss live sessions when reminders arrive ten minutes late. Instructors lose engagement when chat feels sluggish. Polling every thirty seconds on a dashboard with fifty thousand students burns API budget and still feels broken. Toolliyo-style platforms combine structured courses with live cohorts—SignalR fits the moment notifications must reach browsers and mobile web instantly without you operating a separate message broker for v1.
This case study follows a fictional-but-realistic academy, Northline Learning, that added notifications to an existing ASP.NET Core 8 LMS with React frontend.
Requirements they actually had
- Class starting in five minutes — push to enrolled students only.
- Instructor announces break — room-scoped broadcast.
- Assignment graded — private message to one learner.
- System maintenance — admin broadcast to all connected users.
- Reconnect after laptop sleep without duplicate toasts.
Architecture overview
REST APIs remained source of truth for enrollments and grades. SignalR hub delivered events. SQL outbox table queued notifications when hub send failed; background worker retried. Redis backplane enabled scale-out across two API instances on Azure App Service.
// NotificationHub.cs — group strategy
public class NotificationHub : Hub
{
public async Task JoinCourse(string courseId)
{
await Groups.AddToGroupAsync(Context.ConnectionId, $"course:{courseId}");
}
public override async Task OnConnectedAsync()
{
var userId = Context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (userId != null)
await Groups.AddToGroupAsync(Context.ConnectionId, $"user:{userId}");
await base.OnConnectedAsync();
}
}
Authentication without leaking rooms
They issued JWT access tokens with short TTL. React passed token via accessTokenFactory on the SignalR connection. Server validated issuer, audience, and student role before adding to course groups. Critical rule: never trust client-sent courseId alone—server re-checked enrollment from cache before Groups.AddToGroupAsync.
Event types and payloads
Kept payloads small: type enum, title, body snippet, deep link path, createdAt UTC. Full assignment details still fetched via REST after click. Prevented oversized messages that clog connections on mobile networks in India and Nigeria where many Northline students connected.
React client patterns
TanStack Query invalidated course lists on EnrollmentUpdated events. Toast UI debounced duplicate ids client-side using notificationId from server. On reconnect, client called REST /api/notifications/missed?since= with last received timestamp—covering gap if WebSocket dropped during tunnel commute.
Scaling story: week one vs month six
Week one: single instance, in-memory groups, fine for pilot cohort of eight hundred users. Month six: peak three thousand concurrent during webinar—CPU spiked because server broadcast looped all connections. Fix: partition by course groups only, moved global admin broadcast to segmented batches of five hundred with fifty ms delay. Added Redis backplane; sticky sessions on load balancer; documented that scale beyond ten thousand concurrent needed Azure SignalR Service managed tier.
Failure modes they hit
- Proxy timeout — corporate proxies killed silent connections; enabled keep-alive and server timeout tuning.
- Duplicate toasts — fixed with idempotent notificationId stored in localStorage for twenty-four hours.
- Clock skew — all scheduled class reminders used server-side scheduler (Hangfire), not client timers.
AI-assisted content, human-timed delivery
Northline experimented with AI-generated quiz feedback summaries. SignalR delivered "feedback ready" events only after teacher approval workflow completed—avoiding instantaneous AI pushes that felt robotic and eroded trust in accredited programs.
Testing and monitoring
Integration tests spun TestServer hub with WebSocket transport. Production metrics: connection count, group join failures, message send latency histogram, reconnect rate. Alerts when reconnect rate doubled week-over-week—often indicated deployment cert issues.
When not to use SignalR
Email and mobile push still handle offline users. SMS for critical exam proctoring used separate provider. Do not force all notifications through sockets—users disable tabs.
Implementation checklist for your LMS
- Define group naming convention (
user:{id},course:{id}). - Authorize every group join server-side.
- Plan backplane before second API instance.
- Missed notification REST fallback on reconnect.
- Payload size budget under 2 KB for common events.
SignalR turned Northline's product from "refresh the page" to "it told me live." The lesson for Toolliyo builders: pair real-time transport with solid enrollment data, modest payloads, and retry discipline—technology is the easy part; group logic and scale planning separate prototypes from platforms.