Real-Time Apps with Server Push
Most line-of-business screens wait for the user to click refresh. This course teaches you to build Wisej.NET apps that update themselves — pushing changes from the server to every connected browser the instant something happens — all built around the realistic TicketOps Live project. Seven modules cover real-time web architecture, application context and session lifecycle, single-session server push with background tasks, timers and polling fallbacks for update cadence, live data binding and real-time grids, and multi-user push through services and event hubs — before hardening it all for production and shipping the capstone. It's for developers comfortable with the basics who want WebSocket push, background work and live data done the Wisej.NET way.
WebSocket push, background tasks, polling fallback and live data binding for Wisej.NET apps that update themselves — built on the TicketOps Live project.
- Level: Intermediate
- Duration: 8h
- Modules: 7
Curriculum
Module 1: Real-Time Web Architecture in Wisej.NET
Module 1 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the WebSocket Push vs. Polling: Build the Mental Model walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Server-driven real-time architecture: WebSocket push, in-request updates, and polling fallback in the server-side Wisej.NET model. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonWebSocket Push vs. Polling: Build the Mental Model · 13 min
WebSocket Push vs. Polling: Build the Mental Model — a guided Module 1 walkthrough you can run right here in the player.
Narration transcript
Use TicketOps Live to examine how an operations screen receives changes. The important distinction is what triggers an update, because that determines whether the browser must ask for it.
The server owns the controls and their state; the browser presents their widgets. Wisej.NET synchronizes changes between them, allowing background work to deliver visible updates through WebSocket.
During a button request, change the label normally. Wisej.NET includes that change in its response, so an explicit update call would be unnecessary for this request-bound action.
Background work has no pending button response to carry its changes. After updating controls in the session task, explicitly send the changes through the existing WebSocket connection.
Compare the click with the background sequence. One travels with a request response; the other arrives as work progresses, while polling supplies a fallback when WebSocket is unavailable.
Choose a mechanism by its trigger. Request responses follow user actions, push follows server events, and polling checks repeatedly even when no new event has occurred.
Add connection and update status to the console. Explain the selected mechanisms in the architecture note so users and maintainers can tell how current information reaches the screen.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 1 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Build the Live Status Page · 45 min
Objective: Create the first screen of TicketOps Live: a page with a live status strip, a clock label, a progress indicator, and a simulated server heartbeat that updates the browser without a user click. Acceptance: The UI updates once per second after the student clicks Start.; The browser displays changes without additional clicks.; Stop disables the loop within one second.; Starting twice does not create two competing loops.; The code checks whether the page has been disposed..
Module 2: Application Context, Sessions, and Lifecycle
Module 2 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the Who Owns the UI: Sessions, Context, Exit, and Timeout walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Sessions, application context and lifecycle: own the right user’s UI, avoid the static-field trap, and clean up on exit and timeout. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonWho Owns the UI: Sessions, Context, Exit, and Timeout · 13 min
Who Owns the UI: Sessions, Context, Exit, and Timeout — a guided Module 2 walkthrough you can run right here in the player.
Narration transcript
Open the example in two browser tabs to separate identity from session ownership. The same signed-in user can have distinct interface instances that must not share accidental state.
Distinguish the user, session, executing thread, application context, and shared service. A thread can serve different events; it is not the object that owns one user's controls.
Arrange the session labels, lifecycle list, and commands in the Designer. Meaningful control names help connect each visible diagnostic to its handler when inspecting the lifecycle code.
Display session and thread identifiers together. A stable session alongside changing threads makes their different lifetimes visible and explains why thread identity cannot identify the interface owner.
Capture the application context when the page loads and use it for later updates. Guard disposed controls and unsubscribe on exit so background callbacks do not outlive their owner.
Compare the lifecycle logs in both tabs. Closing one releases its subscription while the other continues, demonstrating cleanup scoped to a session rather than a global shutdown.
Place each value with its actual owner. Controls and session services hold session state; globally shared services must not store a current user in static fields.
Build the inspector and write a cleanup rule for every subscription and task. The resulting log should make both creation and release of session-owned work understandable.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 2 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Build a Session Inspector and Lifecycle Logger · 45 min
Objective: Add a diagnostics panel that helps the developer see the current session, application context, browser details, and lifecycle events relevant to real-time updates. Acceptance: The counter is session-specific, not static.; A background update modifies the correct browser session.; The diagnostics panel shows when the background update arrives.; The student can explain what happens after refresh and after session timeout..
Module 3: Single-Session Server Push with Background Tasks
Module 3 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the Progress Without Refresh: Background Import Monitor walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Single-session push: run long work off the click handler, report progress, support cooperative cancellation, and restore UI in finally. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonProgress Without Refresh: Background Import Monitor · 13 min
Progress Without Refresh: Background Import Monitor — a guided Module 3 walkthrough you can run right here in the player.
Narration transcript
Move the long import into a task owned by its session. The page can remain responsive while progress arrives, instead of making the user wait for one long request.
Treat the operation as a lifecycle: prepare controls and cancellation, start the task, report bounded progress, and restore the interface on completion. Every exit needs the same cleanup.
Build the monitor with progress, counts, history, and explicit commands. These controls answer different questions: how far work has progressed, what happened, and what the user can do next.
Create cancellation state before starting the session task, then return from the click. This gives the browser control again while the operation continues under the correct application context.
Check cancellation cooperatively inside the loop. Update internal progress per record but transmit every ten records; catch failures and restore controls in finally so no outcome leaves Start disabled.
Observe the simulated failure after live progress updates. Record diagnostic detail separately from the safe user message, then restore Start to make the failed operation recoverable from the interface.
Batch visible changes and limit progress transmissions, but send completion immediately. Users need a reliable final result more than a separate network update for every processed record.
Test cancellation, deliberate failure, elapsed time, and the final summary in the completed monitor. Each route should end with an understandable status and controls ready for the next action.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 3 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Build a Background Import Monitor · 45 min
Objective: Add a realistic long-running import panel to TicketOps Live. The user can start an import, watch progress, cancel it, and inspect the result. Acceptance: Progress updates appear while the operation is running.; Cancellation works and leaves the UI usable.; Failure is reported without exposing raw stack traces.; The final update always reaches the browser when the session is still alive.; The code does not push more than necessary..
Module 4: Timers, Polling Fallbacks, and Update Cadence
Module 4 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the When Push Is Not Enough: Cadence, Timers, and Fallbacks walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Update cadence and fallback: choose push vs. timers vs. polling, coalesce bursts, and own timer lifecycle per session. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonWhen Push Is Not Enough: Cadence, Timers, and Fallbacks · 13 min
When Push Is Not Enough: Cadence, Timers, and Fallbacks — a guided Module 4 walkthrough you can run right here in the player.
Narration transcript
Choose a refresh rate that serves the business event. Making every internal change visible immediately can consume resources without helping the person reading the screen.
Match the mechanism to the work: push for events, a Wisej.NET timer for periodic refreshes, and a task for a single operation. Polling remains an alternative when needed.
Build the interval controls alongside visible status labels. Showing the selected strategy makes it possible to connect a user's setting with the resulting update behavior.
Apply the chosen interval to the timer while enforcing the minimum. The polling checkbox controls whether repeated requests run, making this fallback an explicit operating choice.
Let incoming events mark the data dirty, then refresh once per timer tick. This combines a burst of model changes into one useful interface update.
Compare the displayed update intervals and their resource tradeoffs. Faster feedback creates more work; slower feedback can feel stale, while polling preserves delivery when WebSocket disappears.
Keep model changes, rendering, push, and polling on distinct schedules. Own timer startup and shutdown, and prevent overlapping ticks from creating uncontrolled concurrent refreshes.
Write a cadence policy for three features with a default and maximum rate. The controls and fallback should implement those deliberate limits rather than encourage unrestricted refreshing.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 4 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Add Polling Fallback and Cadence Controls · 45 min
Objective: Extend TicketOps Live with a dashboard refresh timer and controls to experiment with update cadence. Acceptance: The timer cadence changes visibly.; The events received count can grow faster than the UI updates applied count.; Polling starts and stops with live mode.; No overlapping timer ticks occur.; The student can explain why update coalescing is useful..
Module 5: Live Data Binding and Real-Time Grids
Module 5 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the Live Ticket Board: Updating Data Without Rebuilding the Screen walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Live data binding: update bound collections in session context without rebinding the grid, preserving selection, sort and scroll. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonLive Ticket Board: Updating Data Without Rebuilding the Screen · 13 min
Live Ticket Board: Updating Data Without Rebuilding the Screen — a guided Module 5 walkthrough you can run right here in the player.
Narration transcript
Keep incoming ticket changes visible without restarting the user's work. A live grid succeeds when it reflects new data while preserving the context in which someone is reading or editing.
Modify the bound collection rather than clearing the grid. Rebuilding discards selection, scrolling, sorting, and edits; notifying the binding layer lets existing screen state survive the data change.
Build the grid around its binding source and add a quiet change indicator. Users need to notice incoming updates without a blocking dialog interrupting their current task.
Let Ticket notify property changes and retain timestamps as real date values. Notifications support incremental updates, while typed dates preserve meaningful sorting and formatting choices.
Enter the captured session context before applying shared-feed events. Update the bound list there and notify bindings once, keeping ownership correct while avoiding repeated refresh work.
Follow the new row and resolved ticket while the existing selection stays put. The conflict message asks for attention without discarding the screen state through a reload.
Use temporary markers to reveal changed rows without moving an active edit. When changes conflict, warn the user and let them decide instead of silently replacing their work.
Test live changes with a selection and an open-ticket filter already active. The board should update its data while keeping the user's place and the filter's intended meaning.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 5 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Build the Live Ticket Board · 45 min
Objective: Create a live `DataGridView` that displays support tickets and updates when simulated ticket events arrive. Acceptance: New tickets appear without rebinding the grid from scratch.; Existing tickets update in place.; The selected row is preserved when the row still exists.; The update rate remains controlled.; The student can explain why the bound list is session-owned..
Module 6: Multi-User Push with Services and Event Hubs
Module 6 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the From One Session to Many: TicketHub Events walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Multi-user push: a global event hub raises domain events while each session updates its own UI in its own context. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonFrom One Session to Many: TicketHub Events · 13 min
From One Session to Many: TicketHub Events — a guided Module 6 walkthrough you can run right here in the player.
Narration transcript
Extend ticket updates across sessions without giving the shared hub ownership of their screens. One business event can reach several supervisors, but each session must apply its own visible changes.
Keep controls with the page, context with the session, and shared data with the service. Storing forms in the global hub would mix lifetimes and prevent clean session release.
Build explicit subscribe and unsubscribe commands alongside the notification list and tenant label. These diagnostics make recipient scope and subscription lifetime visible while testing the hub.
Let the shared TicketHub publish events and provide snapshots safely across threads. It cannot choose an application context because it owns shared information rather than a particular user's session.
Capture context, load the snapshot, and handle events through the session. Check disposal and tenant metadata before changing controls, then unsubscribe when the session owner exits.
Compare recipients when each event is published. Contoso and Northwind updates stay within their intended sessions, and closing a subscriber removes it from subsequent delivery.
Carry routing metadata with the event and apply the recipient's filtering policy. When events arrive faster than rendering can handle, add backpressure rather than allowing an unbounded backlog.
Add a metadata field and filtering rule to the hub, then document subscription cleanup. Demonstrate both correct recipients and removal of recipients whose session has ended.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 6 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Build the TicketHub and Multi-User Notifications · 45 min
Objective: Refactor the ticket simulation into a global `TicketHub` service and make multiple browser sessions receive live ticket events. Acceptance: The hub does not store page or control references.; Each session updates its own bound list.; Closing or refreshing a session does not leave a broken subscriber behind.; Multiple sessions can show different filters while sharing the same domain event source.; The student can explain broadcast vs. targeted update..
Module 7: Production Hardening, Deployment, and Capstone
Module 7 of Real-Time Apps with Server Push — the Wisej.NET real-time track. Read the lesson guide and the lab / exam guide, watch the Production Review: From Demo Push to Deployable Real-Time App walkthrough, pass the knowledge check, then complete the hands-on lab in TicketOps Live.
- ReadingLesson Guide · 14 min
Production hardening: verify the full WebSocket path, sticky sessions, health checks, security and observability before deploy. The concept, the mental model, and the production pitfalls — read this before the lab.
- ReadingLab / Exam Guide · 10 min
What you'll build in the hands-on lab, the tasks, the suggested implementation, and the acceptance criteria.
- Video lessonProduction Review: From Demo Push to Deployable Real-Time App · 13 min
Production Review: From Demo Push to Deployable Real-Time App — a guided Module 7 walkthrough you can run right here in the player.
Narration transcript
Review TicketOps Live as a deployed service, not only a successful demonstration. Connection handling, session ownership, cleanup, and diagnostics determine whether the live behavior survives real operating conditions.
Check WebSocket support through every network hop and preserve session affinity. A working server endpoint is insufficient if a proxy blocks upgrades or routes the session to another instance.
Add a Diagnostics page with periodically refreshed health labels. Operators need a visible account of the application's current behavior rather than assumptions based on its intended configuration.
Render the health snapshot so transport mode, active subscriptions, and update rate are visible together. Their relationship helps explain whether fallback or excessive activity is affecting operation.
Choose timeouts, polling intervals, and health limits for the deployment. Training settings illustrate the options, but production values need to reflect the actual workload and infrastructure.
Watch the health panel when the proxy blocks a WebSocket upgrade. Switching to polling keeps updates available and makes the degraded transport explicit instead of presenting a silent failure.
Review termination, unsubscription, throttling, context, fallback, affinity, and security together. A missing lifecycle rule can undermine an otherwise correct event flow after the demonstration ends.
Deliver the console with its completed checklist and explain the ownership decisions. Defend how sessions, cleanup, update cadence, and deployment settings support the behavior users actually observe.
- ReadingAI Coding Exercise · 20 min
Build this module's TicketOpsLive sample with ChatGPT or Claude from a ready-made prompt that points the model at this module's specification, then review, run and extend what it gives you — including against our own reference build on GitHub.
- Knowledge checkModule 7 Knowledge Check · 10 min · Pass mark 80%
- Hands-on labLab — Complete the Production-Ready TicketOps Live Capstone · 45 min
Objective: Complete TicketOps Live and prepare it for a production architecture review. Acceptance: The application runs without duplicate loops or duplicate subscriptions.; The UI remains responsive during background work.; Every long-running operation has completion, cancellation, and failure states.; The multi-user hub does not keep direct references to pages or controls.; Bound grids update incrementally.; The student can defend all deployment assumptions..