SignalR and Realtime
No edit summary
(Adding page to Category:TOC because it contains a TOC.)
 
(8 intermediate revisions by 4 users not shown)
Line 1: Line 1:
==== What is SignalR and what is it used for ====
==== What is SignalR and what is it used for? ====
SignalR is a .net software componenent used for Realtime communication. By realtime we mean that communication done point to point at the time of need.
SignalR is a .net software component used for Realtime communication. By Realtime, we mean communication done point to point at the time of need.


==== How is realtime communication used in MDriven ====
==== How is Realtime communication used in MDriven? ====
We use the newly added realtime functionality in several ways.
We use the newly added Realtime functionality in several ways.
# You can tag an attribute with "Realtime=true" , and systems that use WebApi communcations with an MDrivenServer will have the Attribute invalidated in a very short time after it was committed to the database. This functionality enables you to discover changes and react to them faster with less resource consumption than what you could before.
# You can tag an attribute with "<code>Realtime=true</code>", and systems that use WebApi communications with an MDrivenServer will have the Attribute invalidated in a very short time after it was committed to the database. This functionality enables you to discover changes and react to them faster with less resource consumption than you could before.
# MDrivenTurnkey - javascript client polled the server frequently to see if there where any updates to render, Now the client instead waits for an event from the server "WeGotNews" and then polls. Currently the client will still poll without this event - buut at a much lower frequency (68s instead of 8s)
# MDrivenTurnkey - the Javascript client polled the server frequently to see if there were any updates to render. Now, the client instead waits for an event from the server "WeGotNews" and then polls. Currently, the client will still poll without this event - but at a much lower frequency (68s instead of 8s).
# WPF Wecpof applications did not have the auto polling as Turnkey used - instead a refresh poll was done on ViewOpen. This has now changed and WPF-Wecpof also has the auto refresh. To avoid needing to do the refresh when nothing has changed - we have an AllIsWell-event sent from the MDrivenServer that also gives information on the sync-version-id - that the client can use to decide if a poll is needed or not.
# WPF - Wecpof applications did not have the auto polling as Turnkey used; instead, a refresh poll was done on ViewOpen. This has now changed and WPF-Wecpof also has the auto refresh. To avoid needing to do the refresh when nothing has changed, we have an "AllIsWell" event sent from the MDrivenServer that also gives information on the sync-version-id - that the client can use to decide if a poll is needed or not.


====== Signaling for Realtime ======
====== Signaling for Realtime ======
When a member change PersistenceState from dirty to current - as it does on save complete - it checks if it was tagged with Realtime TV. If so it ends up in Cache_OnRealtimeChangeDetected - from here we signal the Mdr server "RealtimeChangeInClient" with id of object and model-number of the feature. The MDr-Server reacts with sending a RealtimeStateUpdate event over signalR to all clients(Clients are typical ecospaces in TurnkeyServers). Clients call InvalidateIfNotAlready on the specific member that async will check the current state of the member - if it was currently current it is set to invalidated and the InvalidateByRealtimeDone event is fired on the IPersistenceService implementation. Turnkey EcoSpaces has implemented this event (InvalidateByRealtimeDone) with a call to SignalLiveClientsWeGotNews that in turn calls all turnkeyjavascript clilents with AskClientToPullNowWeGotNews (signalR).
When a member changes PersistenceState from dirty to current - as it does on save complete - it checks if it was tagged with Realtime TV. If so, it ends up in Cache_OnRealtimeChangeDetected. From here, we signal the MDriven Server "RealtimeChangeInClient" with the ID of the object and the model number of the feature. The MDriven Server reacts by sending a RealtimeStateUpdate event over signalR to all clients(clients are typical ecospaces in TurnkeyServers).   


=== Updates 2021 Feb ===
Clients check if the object is loaded and if so, call InvalidateIfNotAlready on the specific member that Async will check the current state of the member. If it is current, it is set to invalidated and the InvalidateByRealtimeDone event is fired on the IPersistenceService implementation.
SignalR actually comes in 2 versions; one called SignalR and one SignalRCore. The 2 versions are not message compatible. The 2 versions can act as a client in both .net core and .net Framework(>4.6.1).


As we have the MDrivenServer- core version - and the built in in WPF Prototyper in MDrivenDesigner(.net Framework) - we have now added the capability to connect to a MDrivenServer-Core version from the MDrivenDesigner.
Turnkey EcoSpaces have implemented this event (InvalidateByRealtimeDone) with a call to SignalLiveClientsWeGotNews that in turn calls all Turnkey-Javascript clients with AskClientToPullNowWeGotNews (SignalR). Live clients will ask their TK server for an update - if the client shows and UI that contains this Realtime attribute, it will be accessed and we will discover that it is in an invalidated state. We then fetch it from the DB and deliver it to the client as a normal refresh loop.  


If you have Framework based clients you can also do so by adding the nuget package Microsoft.AspNetCore.SignalR.Client.  
=== Updates 2021 February ===
SignalR actually comes in 2 versions: SignalR and SignalRCore.
* The 2 versions are not message compatible.
* The 2 versions can act as a client in both .net core and .net Framework(>4.6.1).
As we have the MDrivenServer- core version and the built-in WPF Prototyper in MDrivenDesigner(.net Framework), we have now added the capability to connect to an MDrivenServer-Core version from the MDrivenDesigner.


A framework based client that make use of the RealtimeStateSubscriberService will first try and connect to MDrivenServer Framework version with SignalR - if it fails it will then try and connect with SignalRCore.
If you have Framework-based clients, you can also do so by adding the Nuget package Microsoft.AspNetCore.SignalR.Client.  


The Turnkey Javascript client will also first try Framework communication and if failing to connect will switch to core communication.
A Framework-based client that makes use of the RealtimeStateSubscriberService will first try to connect to an MDriven Server Framework version with SignalR. If it fails, it will then try to connect with SignalRCore.


==== Verify SignalR can connect (.net Framework) ====
The Turnkey Javascript client will also first try Framework communication and if it fails to connect, will switch to core communication.
If you are behind a reverse proxy and you have trouble to get SignalR to connect - then just try these calls in browser and make sure they are not blocked:


[https://yoursiteurl/signalr/negotiate?clientProtocol=2.1&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&_=1636029928727 https://yoursiteurl/signalr/negotiate?clientProtocol=2.1]
==== Load balancing with SignalR ====
'''Please note''' that the .Net Framework version as implemented in Turnkey is not compatible with cookie based load balancing.


[https://yoursiteurl/signalr/connect?transport=serverSentEvents&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&tid=5 https://yoursiteurl/signalr/connect?transport=serverSentEvents&clientProtocol=2.1]
==== Verify SignalR can connect (.net Framework) ====
 
If you are behind a reverse proxy and you have trouble getting SignalR to connect, then try these calls in your browser and make sure they are not blocked:
[https://yoursiteurl/signalr/start?transport=serverSentEvents&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&_=1636029928728 https://yoursiteurl/signalr/start?transport=serverSentEvents&clientProtocol=2.1]
* [https://yoursiteurl/signalr/negotiate?clientProtocol=2.1&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&_=1636029928727 https://yoursiteurl/signalr/negotiate?clientProtocol=2.1]
 
* [https://yoursiteurl/signalr/connect?transport=serverSentEvents&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&tid=5 https://yoursiteurl/signalr/connect?transport=serverSentEvents&clientProtocol=2.1]
https://yoursiteurl/signalr/ping?_=1636029928729
* [https://yoursiteurl/signalr/start?transport=serverSentEvents&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&_=1636029928728 https://yoursiteurl/signalr/start?transport=serverSentEvents&clientProtocol=2.1]
* https://yoursiteurl/signalr/ping?_=1636029928729
* [https://yoursiteurl/signalr/reconnect?transport=serverSentEvents&messageId=d-3E0C687C-L%2C0%7CM%2C0%7CN%2C1&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&tid=6 https://yoursiteurl/signalr/reconnect?transport=serverSentEvents&]
[[Category:WebUI]]
{{Edited|July|12|2024}}


[https://yoursiteurl/signalr/reconnect?transport=serverSentEvents&messageId=d-3E0C687C-L%2C0%7CM%2C0%7CN%2C1&clientProtocol=2.1&connectionToken=zCSABES%2F94TT7OXHH9jrLt87wMItb0Ky6D3gZLYzeJTggqSTfVOS2xp87PfV%2Bo3XumUb0uqZvjtb5CMFWP%2FMGS9UtWl0SL1lKESfyWMe9y%2B2SMIl%2Fs%2BBz7zM4EoTF3Xj&connectionData=%5B%7B%22name%22%3A%22clientpushhub%22%7D%5D&tid=6 https://yoursiteurl/signalr/reconnect?transport=serverSentEvents&]
[[Category:TOC]]

Latest revision as of 14:13, 26 March 2024

What is SignalR and what is it used for?

SignalR is a .net software component used for Realtime communication. By Realtime, we mean communication done point to point at the time of need.

How is Realtime communication used in MDriven?

We use the newly added Realtime functionality in several ways.

  1. You can tag an attribute with "Realtime=true", and systems that use WebApi communications with an MDrivenServer will have the Attribute invalidated in a very short time after it was committed to the database. This functionality enables you to discover changes and react to them faster with less resource consumption than you could before.
  2. MDrivenTurnkey - the Javascript client polled the server frequently to see if there were any updates to render. Now, the client instead waits for an event from the server "WeGotNews" and then polls. Currently, the client will still poll without this event - but at a much lower frequency (68s instead of 8s).
  3. WPF - Wecpof applications did not have the auto polling as Turnkey used; instead, a refresh poll was done on ViewOpen. This has now changed and WPF-Wecpof also has the auto refresh. To avoid needing to do the refresh when nothing has changed, we have an "AllIsWell" event sent from the MDrivenServer that also gives information on the sync-version-id - that the client can use to decide if a poll is needed or not.
Signaling for Realtime

When a member changes PersistenceState from dirty to current - as it does on save complete - it checks if it was tagged with Realtime TV. If so, it ends up in Cache_OnRealtimeChangeDetected. From here, we signal the MDriven Server "RealtimeChangeInClient" with the ID of the object and the model number of the feature. The MDriven Server reacts by sending a RealtimeStateUpdate event over signalR to all clients(clients are typical ecospaces in TurnkeyServers).

Clients check if the object is loaded and if so, call InvalidateIfNotAlready on the specific member that Async will check the current state of the member. If it is current, it is set to invalidated and the InvalidateByRealtimeDone event is fired on the IPersistenceService implementation.

Turnkey EcoSpaces have implemented this event (InvalidateByRealtimeDone) with a call to SignalLiveClientsWeGotNews that in turn calls all Turnkey-Javascript clients with AskClientToPullNowWeGotNews (SignalR). Live clients will ask their TK server for an update - if the client shows and UI that contains this Realtime attribute, it will be accessed and we will discover that it is in an invalidated state. We then fetch it from the DB and deliver it to the client as a normal refresh loop.

Updates 2021 February

SignalR actually comes in 2 versions: SignalR and SignalRCore.

  • The 2 versions are not message compatible.
  • The 2 versions can act as a client in both .net core and .net Framework(>4.6.1).

As we have the MDrivenServer- core version and the built-in WPF Prototyper in MDrivenDesigner(.net Framework), we have now added the capability to connect to an MDrivenServer-Core version from the MDrivenDesigner.

If you have Framework-based clients, you can also do so by adding the Nuget package Microsoft.AspNetCore.SignalR.Client.

A Framework-based client that makes use of the RealtimeStateSubscriberService will first try to connect to an MDriven Server Framework version with SignalR. If it fails, it will then try to connect with SignalRCore.

The Turnkey Javascript client will also first try Framework communication and if it fails to connect, will switch to core communication.

Load balancing with SignalR

Please note that the .Net Framework version as implemented in Turnkey is not compatible with cookie based load balancing.

Verify SignalR can connect (.net Framework)

If you are behind a reverse proxy and you have trouble getting SignalR to connect, then try these calls in your browser and make sure they are not blocked:

This page was edited 47 days ago on 03/26/2024. What links here