Communication between MDrivenServers
Line 43: Line 43:


===== Usecase #2 the one to one sender =====
===== Usecase #2 the one to one sender =====
Suppose you have a generic service converting open-document-standard files to pdf's. Your other 250 systems want's to use this capability to produce pdf's - but they need continuous feedback to show to an eager user waiting to see the result. We want to avoid polling the pdf generator to much with "are you done yet" questions but at the same time we do not want our user to wait 5 seconds to long.
Suppose you have a generic service converting open-document-standard-files (.odt) to pdf's. Your other 250 systems want to use this capability to produce pdf's - but they need continuous feedback to show to an eager user waiting to see the result. We want to avoid polling the pdf generator to much with "are you done yet" questions but at the same time we do not want our user to wait 5 seconds to long.


We create an RestPost api on the Pdf-service that receives the raw data but also a guid-string that act as our eventguid. Directly there after we call RealtimeSubscribeToEvent giving the url to the Pdf-service, the guid-string and a eventcookie that we define as 'Viewmodel=DoThisWhenDoneWithPDF&RootId='+self.externalid. We can then just forget about this job and wait for the DoThisWhenDoneWithPDF serverside ViewModel being executed. This will probably pull the finished Pdf from the service - and signal the user with an update of a [[SignalR and Realtime|realtime]] tagged attribute - that updates immediately if someone is watching it.
We create an RestPost api on the Pdf-service that receives the raw data but also a guid-string that act as our eventguid. Directly there after we call RealtimeSubscribeToEvent giving the url to the Pdf-service, the guid-string and a eventcookie that we define as 'Viewmodel=DoThisWhenSomethingImportantHappendWithMyPDF&RootId='+self.externalid. We can then just forget about this job and wait for the DoThisWhenSomethingImportantHappendWithMyPDF serverside ViewModel being executed. This will probably pull the finished Pdf from the service - and signal the user with an update of a [[SignalR and Realtime|realtime]] tagged attribute - that updates immediately if someone is watching it.

Revision as of 18:52, 15 November 2020

If you build a whole (micro) service universe you will soon notice a need for events triggered from one system sent to another.

This can - and is - often handled as Rest-api's on two systems that call each other. While this strategy may get the job done you have an issue with the fact that the two systems must know about each other - and this quickly turns into a spaghetti tangled web of services that cannot really change without breaking something.

A much better approach is to have the more generic of the two systems expose a generic callback - an event.

Such events are best implemented by an open socket that can be used by the generic system to signal events even if it knows nothing about the listener - that in turn may cause action in the caller.

In .net SignalR is implementing this infrastructure.

In MDrivenServer we use SignalR to enable internet signaling and event sending to subscribers

realtimesubscribetoevent

Create an action column on a serverside ViewModel named realtimesubscribetoevent. You will need these columns:

  • realtimehub = the MDrivenServer-url to the system to subscribe to - leave blank for THIS system
  • eventguid = a unique id (as a string) that makes the this event unique on instance level - you will want to share this eventguid with the event sender - because that will make your eventcookie come back to your system in the ReceiveEvent(theEventGuid, theEventCookie) callback
  • eventcookie = what you want the server to send back on event - suggested value 'Viewmodel=SomeVM&RootId='+self.externalid

RealtimeTriggerEvent

Create an action column on a serverside ViewModel named RealtimeTriggerEvent. You will need this column:

  • eventguid = a unique id (as a string) that makes the this event unique on instance level - you want to share this eventguid with the event subscriber - no matter how many subscribers you have - they will receive their eventcookie

The receiving MDrivenServer

The receiving MDrivenServer will use the eventcookie that comes back when the event is triggered in the ReceiveEvent(theEventGuid, theEventCookie) and create an SysAsyncTicket with the ViewModel and RootId taken from the cookie.

If you have a non MDrivenServer as a event giver - and you want to hook up the MDrivenServer as an event listener - then the event sending system must allow for the following SignalR api to be called and sent:

method SubscribeToEvent(string eventguid,string clientcookie );
event ReceiveEvent(string eventguid, string ClientCookie);

The event sending MDrivenServer

The event sending MDrivenServer will upon executing the RealTimeTrigger serverside vm action use the eventguid and call the ReceiveEvent that will filter out the connected listening clients on eventguid - and send the clientcookie

If you build another -non MDrivenServer - system that wants to consume events from an MDrivenServer you must allow for the following SignalR api:

event ReceiveEvent(string eventguid, string ClientCookie);

and in this you must parse the ClientCookie you sent in on SubscribeToEvent and act as you see fit.

Usecases

Usecase #1 the multisender

Suppose you have an IOT device collecting movement in an area. You want 250 other services to react to this detection urgently - but you want to avoid to have 250 services to poll the IOT device continuously because the device is not on a fast server and the network connection is slow. A much better solution is to let the IOT device signal when a detection is done. A naïve implementation lets the 250 services register in the IOT device - and have the IOT device roll through the list to try and connect to the clients one by one. This may fail because some of the clients are behind firewalls, and some has been decommissioned recently.

Better solution: We let the IOT device expose an eventguid that is "MovementDetected". All the 250 services call IOTDevice.SubscribeToEvent("MovementDetected",clientcookie) - all the 250 listeners have their own way of reacting - so all give different clientcookies. On detection of movement all the 250 gets notified swiftly on an already open socket - and depending on need the client may follow up with an authenticated RestCall to the Device to get further details important for its function.

Usecase #2 the one to one sender

Suppose you have a generic service converting open-document-standard-files (.odt) to pdf's. Your other 250 systems want to use this capability to produce pdf's - but they need continuous feedback to show to an eager user waiting to see the result. We want to avoid polling the pdf generator to much with "are you done yet" questions but at the same time we do not want our user to wait 5 seconds to long.

We create an RestPost api on the Pdf-service that receives the raw data but also a guid-string that act as our eventguid. Directly there after we call RealtimeSubscribeToEvent giving the url to the Pdf-service, the guid-string and a eventcookie that we define as 'Viewmodel=DoThisWhenSomethingImportantHappendWithMyPDF&RootId='+self.externalid. We can then just forget about this job and wait for the DoThisWhenSomethingImportantHappendWithMyPDF serverside ViewModel being executed. This will probably pull the finished Pdf from the service - and signal the user with an update of a realtime tagged attribute - that updates immediately if someone is watching it.

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