Click here to Skip to main content
15,884,298 members
Articles / Web Development / ASP.NET
Tip/Trick

Exploring Signal-R to make WPF Application Interactive

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
13 Oct 2021CPOL4 min read 11.3K   686   10   1
A WPF application can be made more interactive and deployment friendly by using SignalR to our advantage. This is Part 1 showing how SignalR can be implemented in a WPF application for two-way communication and synchronization.
WPF is used to build desktop application with rich UI. But how do we overcome the limitation of syncing live data? How do we make deployments more managed and avoid database locks in client server scenarios. Signal-R helps provide an answer to many of these questions.

Introduction

Signal-R is a library that enables real time interaction between a server and multiple clients environment. A desktop or WPF application enables us to explore the full capacity of our hardware but takes a step behind when we want real time connectivity between multiple clients. Who could be working parallely. Since WPF applications are deployed on individual client machine, the deployments need to be managed to avoid centralized database locks. Trust me, no matter how many reminders you send regarding a deployment, no one really stops working to give you a way. What do you do then? Well, we push them out of the system!!

Another way we have used SignalR is to push data updates and perform data reloads on all connected clients when the data is updated in the Server. The SignalR broadcast can be integrated with entity framework to identify the entities that are updated and force a reload of the same on all connected clients. You can refer to the solution in this article.

The third use of SignalR is to synchronize cache on the services and all WPF clients apps when the master data or the user roles are changed. When the administrator makes some application configuration changes or users are added to the system and wants to push this information to all connected clients to use it without a need to reopen the application.

Using the Code

So in this first article, I will demonstrate how to setup SignalR listener in a WPF application and make the WebApi service a broadcast hub which can push messages to all the connected clients. Then, I will demonstrate how we can make deployments manageable by sending a "Poison Pill" to all the connected clients. This will force the client apps to close.

The WebApi service which works as the broadcast hub need not be a standalone service. In a SOA, the existing WebApi which the enterprise uses can be enhanced to work as an hub. In the attached solution, I have created a webapi service which acts as the broadcast hub. We need the Microsoft.AspNet.SignalR nuget packages to be installed on the Web API project. The primary file needed is the Broadcasthub.cs which is defined inside the infra project which manages the connection and disconnection of clients to the hub. By default, signalR is hosted on the path http://<baseurl>/signalR.

To send a message to all the connected clients, we can use the code as follows. In fact, it can be enhanced to send the message to only selected client connections by tracking the connectionId. Let me know if you want to know how to do that! And I will send you another sample. :)

C#
var context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>();    
context.Clients.All.PoisonPill(new PoisonPill() { Message = req.Message });

So here, we are sending a PoisonPill message to all clients. This can be triggered from an admin page which can be used to trigger the message when we want all connected client apps to terminate (not to be evil, use it when you want to do some service or DB deployments which might lead to deadlocks).

Now comes the part about adding the handlers on the WPF application which will listen to messages posted by the broadcast hub and show a popup on the client app notifying of a deployment and allowing the user 60 seconds before it closes the client app automatically.

For the client app, refer to the code with the ClientApp folder in the attached sample. The SignalR client has been created as a singleton instance. It is initialized from the App's OnStartup event. Once the client is initialized, the Connect method is called which uses the API endpoint address to connect. This very SignalRClient class contains the logic for retrial of connection for a certain time span in case it fails. Inside the Initializer, we map the handlers for the various signalR messages we want to subscribe to.

C#
var hubProxy = connection.CreateHubProxy("BroadcastHub");
hubProxy.On<PoisonPill>("PoisonPill",
                message => Messenger.Default.Send(message));

So this way, multiple types of client can subscribe to selective messages from a single broadcast hub.

Now on the main window view model, we can attach the eventhandlers as follows:

C#
Messenger.Default.Register<PoisonPill>(this, OnPoisonPillMessage);

So every time the broadcast server sends a poisonpill message, the "OnPoisonPillMessage" method will be called. Now the logic for closing the application automatically is handled within this method.

The full code of the server and client app is attached for your reference.

SignalR makes the WPF application a lot more interactive in the multi user scenarios.

History

  • 13th October, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Infosys Limited
India India
Since my first handshake with coding in 1996, I knew its a world for me. Started the professional deep dive in 2006 and never felt like leaving the pool since.

Comments and Discussions

 
QuestionNice work! Pin
DanW5214-Oct-21 10:00
professionalDanW5214-Oct-21 10:00 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.