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:

Creating 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 each 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 lets 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:
[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:

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 new hub for us and can easily be done with the following code (note Startup in the following code refers to the class we just created):

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 desire, keeping in mind that this tutorial focuses on getting desktop applications to work with SignalR. Web applications also works greate 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:

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 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:

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:

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:

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 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:

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

The On method takes 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 it’s 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 it’s potential uses.