🚀 Welcome to MDriven Learn –  MDriven is now on Discord!  Don’t miss the latest Release Notes.
SignalR and Realtime
This page was created by Hans.karlsen on 2020-10-13. Last edited by Wikiadmin on 2026-07-29.

You can use SignalR-based realtime signaling to make MDriven clients notice selected committed changes quickly, without relying on frequent polling; this page is for modelers and administrators configuring MDrivenServer clients such as MDriven Turnkey and WPF-Wecpof.

What realtime does

SignalR is a .NET communication component for sending a signal to connected clients when an event occurs. In MDriven, realtime signaling is a notification mechanism: it tells a client that data may need refreshing. The client then performs the normal refresh path and obtains current data from the database.

This differs from continuously asking the server whether anything changed. A Turnkey JavaScript client waits for a server event named WeGotNews and polls when it receives that event. It still polls when no event is received, but at a much lower frequency: 68 seconds instead of 8 seconds.

Use realtime for data where a delay is visible or disruptive, such as a chat channel, a shared status display, or a work queue. Do not mark every attribute as realtime. Each marked change creates signaling work and consumes network capacity.

Enable realtime for a model attribute

Mark the attribute whose change should cause connected clients to refresh.

  1. Identify the attribute that represents a meaningful change to the UI.
  2. Set the attribute tag value to Realtime=true.
  3. Ensure that the relevant ViewModel reads that attribute, directly or as part of the data it presents.
  4. Save the changed object. Realtime signaling occurs when the member reaches persistence state current after the save completes.
  5. Test with two clients that display the same data: change and save the value in one client, then confirm that the other client refreshes promptly.

For example, a chat model can have a LatestMessage attribute on Channel. The send action sets CurrentChannel.LatestMessage to the current date and time before saving a new message. When LatestMessage has Realtime=true, clients displaying that channel are notified and refresh the message list. Without the tag, the changed list is found on the next ordinary poll instead.

What happens after a save

The following sequence explains why the tag must be placed on an attribute that the displayed data depends on.

  1. A tagged member changes and is saved. When its persistence state changes from dirty to current, MDriven detects the Realtime=true tag.
  2. The client signals RealtimeChangeInClient to MDrivenServer, including the object ID and the model number of the changed feature.
  3. MDrivenServer sends a RealtimeStateUpdate through SignalR to connected clients, which are typically EcoSpaces in Turnkey servers.
  4. A receiving client checks whether it has the object loaded. If it does, it calls InvalidateIfNotAlready for the affected member.
  5. The member becomes invalidated. The next asynchronous access checks its current state and retrieves current data when needed. The persistence-service implementation raises InvalidateByRealtimeDone.
  6. Turnkey EcoSpaces handle that event by signaling live JavaScript clients with WeGotNews. A live client asks its Turnkey server for an update; if its UI uses the invalidated realtime attribute, the normal refresh path reloads the data from the database and renders the result.

Realtime therefore does not push the changed database value directly into every browser. It invalidates selected loaded data and prompts the normal refresh mechanism to retrieve it.

Client behavior

Client Realtime behavior
MDriven Turnkey JavaScript client Waits for WeGotNews, then polls for updated data. It also retains a lower-frequency background poll of 68 seconds when no event arrives.
WPF-Wecpof Receives automatic refresh support. Earlier behavior used a refresh poll when a View opened. MDrivenServer can send an AllIsWell event containing a sync-version ID, which the client can use to decide whether polling is necessary.

A realtime-tagged attribute can also be changed by a server-side job. The important condition is that the changed attribute has realtime enabled and reaches the committed state.

SignalR and SignalR Core compatibility

SignalR exists in two versions: SignalR and SignalR Core. They are not message compatible.

Both versions can act as a client from .NET Core and from .NET Framework later than 4.6.1. This allows the built-in WPF Prototyper in MDriven Designer, which runs on .NET Framework, to connect to a core version of MDrivenServer.

For a framework-based client, add the NuGet package Microsoft.AspNetCore.SignalR.Client when SignalR Core client support is required. A framework-based client using RealtimeStateSubscriberService first attempts to connect to a framework MDrivenServer using SignalR. If that fails, it attempts SignalR Core. The Turnkey JavaScript client follows the same order: it first attempts framework communication and switches to core communication if it cannot connect.

Load balancing limitation

The .NET Framework SignalR version used in Turnkey is not compatible with cookie-based load balancing. Account for this limitation when placing Turnkey behind a load balancer.

Verify a .NET Framework SignalR connection

If SignalR cannot connect through a reverse proxy, test the SignalR endpoints in a browser and confirm that the proxy does not block them. Replace https://yoursiteurl with the public URL of your site.

https://yoursiteurl/signalr/negotiate?clientProtocol=2.1
https://yoursiteurl/signalr/connect?transport=serverSentEvents&clientProtocol=2.1
https://yoursiteurl/signalr/start?transport=serverSentEvents&clientProtocol=2.1
https://yoursiteurl/signalr/ping?_=1636029928729
https://yoursiteurl/signalr/reconnect?transport=serverSentEvents&

If one of these requests is blocked, correct the reverse-proxy or firewall rule before investigating the MDriven client. SignalR can use fallback techniques, including long polling, when WebSockets are unavailable; however, the endpoints above must remain reachable for the .NET Framework SignalR connection.

Realtime events between MDrivenServers

Attribute invalidation is not the same feature as sending application events between systems. To subscribe to or trigger named SignalR events between MDrivenServers, use the server-side ViewModel actions described in Documentation:Communication between MDrivenServers. That page covers RealtimeSubscribeToEvent, RealtimeTriggerEvent, event cookies, and the security requirement not to send sensitive data in open, unauthenticated event payloads.

Design checklist

  • Mark only attributes whose committed change should prompt an immediate UI update.
  • Use an attribute that the displayed ViewModel data depends on. For example, use LatestMessage to notify a chat view that its message collection needs reloading.
  • Test with separate clients connected to the same MDrivenServer and displaying the affected object.
  • Keep the normal polling and refresh behavior in mind: realtime is a prompt to refresh, not a replacement for data retrieval.
  • Verify proxy and firewall access to the SignalR endpoints before treating a missing update as a model issue.
  • Do not use cross-server SignalR events to carry sensitive values; use them to trigger a protected follow-up request as described in Documentation:Communication between MDrivenServers.

See also