Click here to Skip to main content
15,884,388 members
Articles / Programming Languages / C#

Implementing SignalR in Desktop Applications

Rate me:
Please Sign up or sign in to vote.
4.91/5 (54 votes)
6 Aug 2014CPOL7 min read 205.6K   12K   90   39
Step-by-step walkthrough to implement SignalR in desktop applications

Introduction

Well, let us start at the beginning and firstly discuss what SignalR is.

SignalR is a newish Microsoft technology that enables us to build real-time applications, where clients can push data to the server, and the server can push data to all clients.

It works with the new HTML5 WebSockets API that enables bi-directional communication between clients (desktop applications, as well as browsers) and server. If WebSockets are not available, it gracefully falls back onto other technologies, without any changes in code. It also builds on OWIN (Open Web Interface for .NET).

This makes it very useful to build real-time applications, such as chat applications, monitor dashboards, etc.

The aim of this blog post is show how we can achieve this real-time communication between a server, and a desktop application. For the people starting to feel anxious, rest assured, this is not as complicated as it might sound. If you follow the steps below, you will see it isn't such a daunting task at all.

Let us break the explanation down to the following steps:

  • Create the SignalR hub for the server
  • Create desktop application that connects to the SignalR hub
  • Send message from the client application to the server
  • Send message from the server to the client

Using the Code

Create the SignalR Hub

One of the most important things to understand when implementing SignalR is that at the center of it all, is what we call a "Hub". This hub is what enables communication between the server and clients.

Before we create a sample hub, we first need to decide how we want to host the hub. There are various options when it comes to hosting a SignalR hub, all with their own advantages and disadvantages.

Some of the hub-hosting options available to us are:

  • Self-hosting
  • IIS-hosting
  • Windows service-hosting

The service-hosting options for example is a good choice if you need the hub to always be on, and it can for example be restarted automatically when the machine restarts.

To keep things simple for this post, I am going to make use of the self-hosting option, and we are going to host the SignalR hub inside a simple console application.

So let's get started:

  • Open Visual Studio, and create a new Console application
  • We will need to install some Nuget packages onto this application. You can do this through the GUI, or by running the following commands in the Package Manager Console:
Install-Package Microsoft.AspNet.SignalR.SelfHost
Install-Package Microsoft.Owin.Cors

Next let us create the hub itself:

  • Create a new public class and call it something like TestHub
  • Let TestHub inherit from Hub
  • You can optionally give the Hub a new name by slapping a HubName attribute on the class, like so:
C#
[HubName("TestHub")]

At the moment, the hub has no functionality yet, but let us start by seeing how easy it is to start up the hub when the console application is started.

Create a new class called Startup, or whatever you like and add the following code to it:

C#
public void Configuration(IAppBuilder app)
{
    app.UseCors(CorsOptions.AllowAll);
    app.MapSignalR();
}

This simply enables the hub to communicate cross-domain, and correctly maps all the SignalR hubs in the application for us.

Next step is to add the call in the application's entry point to create a new hub for us and this can easily be done with the following code (note Startup in the following code refers to the class we just created):

C#
static void Main(string[] args)
{
    string url = @"http://localhost:8080/";
    using (WebApp.Start<startup>(url))
    {
        Console.WriteLine(string.Format("Server running at {0}", url));
        Console.ReadLine();
    }
}

That is all we need to do to create a SignalR hub.

You can test that everything is working as expected by running the application and browsing to the following URL in your browser. If it is working, you will see a bunch of SignalR related code.

http://localhost:8080/signalR/hubs

So far, so good? Easy, right? :)

Let us now move on to the desktop application.

Creating the Desktop Client

For this post, I am going to be using another console application, but you can use Winforms, WPF, or whatever your heart desires, keeping in mind that this tutorial focuses on getting desktop applications to work with SignalR. Web applications also work great with SignalR, but will not be covered in this post.

First, we will need to install the SignalR client Nuget package onto the client project. As with the Hub, this can be done either via the GUI, or the Package Manager Console. The commands for the console are given below:

Install-Package Microsoft.AspNet.SignalR.Client

Once this is done, we need to create a proxy to the HubConnection. This can easily be done with a couple of lines of code:

C#
static void Main(string[] args)
{
    IHubProxy _hub;
    string url = @"http://localhost:8080/";
    var connection = new HubConnection(url);
    _hub = connection.CreateHubProxy("TestHub");
    connection.Start().Wait();
}

That is all there is to it to connect to a SignalR hub.

Note at this stage the application will close after the connection is made, because it has nothing keeping it running. We will improve on this in the next step.

Next, we will tackle the actual communication between the server and client.

Send Message from the Client

Caveat

The most important thing to understand when setting up communication between the server and client is that most of SignalR makes use of dynamic objects, so spelling is very important. Fear not non-grammar Nazis. I am not talking spelling as in the words are spelt correctly, according to some dictionary, only that the same spelling of method names are used on the server and client. The reason for this will soon become clear.

To keep things simple for this post, let's create a method on the server that will receive some string value, and return the length of the string in the client.

I'll admit, this is not the most exciting thing on earth to do with a realtime application, but humour me.

To start, in the Client, we need to add code that will invoke a specific method on the Hub, and this is where spelling becomes important. So in the client, add the following after the part where the SignalR connection is opened:

C#
string line = null;
while ((line = System.Console.ReadLine()) != null)
{
    _hub.Invoke("DetermineLength", line).Wait();
}

Note the DetermineLength portion in the section above. SignalR will attempt to call a method on the TestHub with that exact same name and parameters, in this case a string value.

So let us now create the corresponding method, that will receive this sent data, on TestHub by adding the following code:

C#
public void DetermineLength(string message)
{
    Console.WriteLine(message);
}

Note that even though we want to return something, this method has a void return type.

We can now run the solution and ensure that the message arrives at the TestHub as expected by verifying that it gets printed to the console on the server.

If you can't see anything being printed in the console, verify that the method names are spelled exactly the same.

After we have verified that our messages are being received and processed by the hub, we can focus on communicating back to the client application.

Send Message from the Server

There are various ways to communicate back with clients connected to the hub. We can respond only to the calling client, send data to all connected clients, or even just a select few. We might delve into this in a future post. For now however, we are going to respond to all connected clients.

So let us concatenate the length of the string to the received message and respond back to the client(s). Add the following lines to your code:

C#
public void DetermineLength(string message)
{
    Console.WriteLine(message);
    string newMessage = string.Format(@"{0} has a length of: {1}", message, message.Length);
    Clients.All.ReceiveLength(newMessage);
}

Note the ReceiveLength in the code above. SignalR will attempt to call a method on the client with that exact same name and parameter.

So let's go back to our client application and add the code that will receive this data, and do something with it.

In our client application, add the following code:

C#
_hub.On("ReceiveLength", x => Console.WriteLine(x));

The On method specifies a method name and an action. So whenever the SignalR hub sends a message to the method, that specific action will get executed. In our example, it will just print out the message with its length to the console.

And there, we have it! Bidirectional communication using SignalR. Gold star for you!

We can now even have multiple client applications running and each one will respond to other's input as well. Go ahead, try it. You know you want to...

Conclusion

In this post, we have seen how simple it is to create a realtime application with SignalR. It is a very powerful technology, and we have just scraped the surface, but hopefully this article is enough to get you interested and excited about the SignalR and its potential uses.

License

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


Written By
Software Developer Inivit Systems
South Africa South Africa
I am currently employed by Inivit Systems. Here we strive to use cutting edge technologies, in order to provide our clients with the best possible software and continue to offer them a competitive edge.

We are responsible for all kinds of applications, ranging from web applications to desktop applications, including integration into some older legacy systems.

I love programming and solving puzzles, but beside that I enjoy experimenting with new technologies, reading, watching movies and relaxing with friends.

Comments and Discussions

 
Praisereally helpful article and appriciable.. thanks Pin
Kunwar Saurabh3-Aug-20 23:10
Kunwar Saurabh3-Aug-20 23:10 
QuestionComo hacerlo en windows form ?? Pin
Member 1402898123-Oct-18 19:40
Member 1402898123-Oct-18 19:40 
QuestionHigh availability for All Connected Clients Pin
kiquenet.com18-Aug-18 23:49
professionalkiquenet.com18-Aug-18 23:49 
PraiseGreat article Pin
aarredondo17-Jun-17 7:25
aarredondo17-Jun-17 7:25 
QuestionCan I fill the WebApp.Start's url with local computer's ip, and then other devices can connect to the computer by signalr? Pin
akira3215-Jun-17 23:42
akira3215-Jun-17 23:42 
AnswerRe: Can I fill the WebApp.Start's url with local computer's ip, and then other devices can connect to the computer by signalr? Pin
Member 1341242115-Sep-17 14:12
Member 1341242115-Sep-17 14:12 
QuestionHttpListenerException: The process cannot access the file because it is being used by another process Pin
Daniel Smolka10-May-17 0:01
Daniel Smolka10-May-17 0:01 
QuestionWPF as Client in same PC Pin
Member 810403823-Feb-17 15:25
Member 810403823-Feb-17 15:25 
QuestionCan I used to with https? Pin
Ruben Misrahi19-Jan-17 5:26
Ruben Misrahi19-Jan-17 5:26 
QuestionUnable to send messages from server to client Pin
NaniSanthosh21-Dec-16 2:28
NaniSanthosh21-Dec-16 2:28 
PraiseGreat article Pin
KrishanGahlot9-Oct-16 20:13
KrishanGahlot9-Oct-16 20:13 
PraiseMy Vote of 5 Pin
Mike Chibaka5-Oct-16 9:01
Mike Chibaka5-Oct-16 9:01 
QuestionUnable to send message to Server Pin
amarendrap_d14-Sep-16 5:57
amarendrap_d14-Sep-16 5:57 
AnswerRe: Unable to send message to Server Pin
N. Bons6-Jun-17 22:15
N. Bons6-Jun-17 22:15 
QuestionHow would you invoke the Configuration method in console application? Pin
Yashashwi Srivastava11-Jul-16 20:04
Yashashwi Srivastava11-Jul-16 20:04 
Question+5, and a small Typo Pin
Kevin Marois15-May-16 8:04
professionalKevin Marois15-May-16 8:04 
QuestionSend message for special user. Pin
Ar.Gorgin20-Feb-16 22:25
Ar.Gorgin20-Feb-16 22:25 
QuestionQuick question Pin
Juwi_uk13-Sep-15 21:47
Juwi_uk13-Sep-15 21:47 
AnswerRe: Quick question Pin
Member 123656179-Oct-16 13:13
Member 123656179-Oct-16 13:13 
AnswerRe: Quick question Pin
Member 123656179-Oct-16 13:54
Member 123656179-Oct-16 13:54 
QuestionWinform as a Client Pin
stixoffire11-Sep-15 10:15
stixoffire11-Sep-15 10:15 
SuggestionFramework Version Requirement Pin
stixoffire8-Sep-15 9:28
stixoffire8-Sep-15 9:28 
QuestionScalability? Pin
RAND 45586614-Aug-15 8:33
RAND 45586614-Aug-15 8:33 
QuestionI can't able to install this nuget Pin
Member 914124613-Jul-15 23:47
Member 914124613-Jul-15 23:47 
Question5 and one question Pin
Win32nipuh4-Mar-15 18:51
professionalWin32nipuh4-Mar-15 18:51 
How server can send message to all clients?
For example: server works 5 minutes and then sends message to all clients.

As I see here is a formal way: establish connection inside the server app to self and then send message.
Does any another way exist?

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.