Part 5 — Use notifications to update the User Interface
This series describes the implementation of a User Interface driven by an Elsa workflow engine. In this part, we will investigate more about how the engine efficiently communicates with UI.
In the previous section, timing issues were addressed, and concluded the necessity of having an update communication signal from the engine. Let’s implement that.
The implementation relies on the implementation of signalr in the client. Therefore, package references need to be added:
- Microsoft.AspNetCore.SignalR.Client
- Microsoft.AspNetCore.SignalR.Common
ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.
SignalR can be used to add any sort of “real-time” web functionality to your ASP.NET application. While chat is often used as an example, you can do a whole lot more. Any time a user refreshes a web page to see new data, or the page implements long polling to retrieve new data, it is a candidate for using SignalR. Examples include dashboards and monitoring applications, collaborative applications (such as simultaneous editing of documents), job progress updates, and real-time forms.
SignalR also enables completely new types of web applications that require high frequency updates from the server, for example, real-time gaming.
SignalR provides a simple API for creating server-to-client remote procedure calls (RPC) that call JavaScript functions in client browsers (and other client platforms) from server-side .NET code. SignalR also includes API for connection management (for instance, connect and disconnect events), and grouping connections.
The main implementation resides in the detail page of the workflow instances:
Note: in this code the OnInitializedAsync() method should be OnParametersSetAsync so when for some reason the url is changed in the browser to another workflowinstanceid the updates are indeed for the correct workflow instance.
Main functionality
When the page is loaded the page subscribes to the communication channel for the WorkflowInstanceId. This channel is a group of listeners that are interested in anything related to this workflow.
To avoid double subscriptions first the leave group is invoked. After that a listener is activated. This is done by handing over the method needed to be called when a notification arrives.
After that, the page’s working is similar to the other implementation of the workflow instance detailed page.
On each notification, the registered method is called. The notification holds information about the activity that triggered the notification, like if it is a user task.
If it is a user task and the page is not handling a user task at this moment, the user task is loaded into the page. Otherwise, it will just update the rendering to show the notification description.
You may wonder how these notifications are transmitted. Well, on the engine, some parts need to be implemented in order to transmit these messages.
Hub
The SignalR Hubs API enables you to call methods on connected clients from the server. In the server code, you define methods that are called by client. In the client code, you define methods that are called from the server.
The hub has 2 functions: to join or leave a group. In this implementation the hub has no sending functionality. The client can’t send notifications yet. You could implement it for having a locking mechanism. Multiple clients can open the same workflow. Sending a notification which client is activating the task, could be handy.
Notifiers
The notifier is an element used in the engine to activate notifications. Which notifications are sent is determined by implementing interfaces. This interface selection allows you to select which notifications are relevant to be broadcasted. Furthermore, you can determine for yourself what the message of each notification hold. This content in the notification allows the UI only to act if it is a user task or not.
Registering notifiers in the startup
Finally, the signals and the notifiers need to be registered
And by doing this, the UI will respond to the changes in the workflow and, open UI forms when needed.
This makes the UI flexible and generic, with enough capabilities to customize the layout and working of the UI. Everything the engine is providing regarding the UI is optional and not required to implement.
In the final part, we will look at the possibility of starting a workflow that begins with a user task. The current implementation only works for workflows that are instantiated.
Next: Part 6 — starting workflows (coming soon)
Used version: Elsa 2.10.467