SignalR is an amazing framework that delivers a real-time and bidirectional messaging platform. SignalR provides several options to reach its goal, but in this chapter we'll start simple and use the most basic API to set up a persistent and real-time channel: Hubs. A Hub is a special class that SignalR will expose to all the connected clients, allowing them to make Remote Procedure Calls (RPC) to it. Inside the Hub, the developer will also have a set of special objects to use in order to perform calls back onto the connected clients.
There is a very important detail to highlight: SignalR is composed of a server-side library and a set of client-side libraries. In every working solution, you will always need to use both; you will need to expose the server-side endpoints and connect to them using the most appropriate client library. SignalR will do the rest, and you will experience a very natural, simple, and bidirectional programming model.
All the recipes in this chapter will be classic "Hello World" applications. Nothing fancy or exciting will be happening, but all of them will clearly illustrate what can be achieved and how. The Adding a Hub to an ASP.NET project and Adding a Hub to a self-hosting application recipes will show you how to prepare a server portion of a SignalR application using the Hub type in different hosting contexts, whereas the Connecting to a Hub from a JavaScript client and Connecting to a Hub from a .NET application recipes will illustrate how to write client-side code to connect to it from different types of client processes. Each recipe has the goal to be fully functional, therefore all of them will in some way provide at least some hints about the missing counterparts. Server-side recipes will have minimal client code in place, and client-side ones will either contain a basic Hub to connect to or refer to one created earlier, but for all of them, the focus will remain on the actual topic of the recipe.
SignalR sets a clear separation between the actual messaging runtime and the hosting environment. Although the host could be any plain old .NET-based process, the most natural context where you can add a SignalR Hub is inside an ASP.NET project, which is the topic of this recipe. Later in this chapter, we'll see how to host it in a different context.
This recipe will concentrate on the server-side; however, some minimal client-side code will also be added to be able to fully demonstrate a complete, although trivial, client-server connection.
There are three main types of ASP.NET projects:
A Web Forms application
An MVC application
A website
The process of creating them is a fairly common task, so we are going to skip the details. If you want more information, you can refer to the Appendix A, Creating Web Projects at the end of the book and check how to generate them step by step. In this recipe, we will be covering all of them at once, highlighting the points where there's some difference across those types.
Note
In order to show a complete sample for all three cases, the code that comes with this book will contain three separate projects, called Recipe01_WF
(for the Web Forms sample), Recipe01_MVC
(for the MVC project), and Recipe01_WS
(for the website).
Before proceeding, please pick one of them and create your project in Visual Studio 2013.
We're ready to actually start adding the SignalR bits. Let's start with the Hub with the following steps.
From the Project menu, select Add New Item (you can also use the project context menu from Solution Explorer or the Ctrl + Shift + A keyboard shortcut), click on the Web folder, and then select the SignalR Hub Class (v2) template; specify EchoHub
as the name and click on OK as shown in the following screenshot. Make sure you have selected the v2 Version because we want to target SignalR 2.0.

Visual Studio will add a new file called EchoHub.cs
with some boilerplate code inside.
Let's edit the file content to make it look like the following code snippet:
using System.Diagnostics; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; namespace Recipe01 { [HubName("echo")] public class EchoHub : Hub { public void Say(string message) { Trace.WriteLine(message); } } }
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
The following lists the important points here:
The necessary
using
directives are listed at the top of the file.The
EchoHub
class is derived fromHub
, which comes fromMicrosoft.AspNet.SignalR.Hubs
and makes the server-side SignalR API available to our class.The class is marked with the
HubName
attribute, which allows us to give the Hub a friendly name to be used by the clients; if we don't use theHubName
attribute, the Hub name will be the same as the class name (in this case, it would beEchoHub
).Our Hub contains a method called
Say()
. This is just a sample method we'll use to show how to expose Hub endpoints. On every call, it will just output the value of themessage
parameter in the debugger Output window, or in any trace listener we may want to configure.
The class namespace is not so important. Here, I'm choosing the same name as the project name; it's the recommended way, but it does not have to be like that.
From the Project menu, select Add New Item again, click on the Web folder, and then select the OWIN Startup class template. Specify
Startup
as the name and click on OK, as shown in the following screenshot:Visual Studio will add a new file called
Startup.cs
with some code inside it.Let's edit the file content to make it look like the following:
using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(Recipe01.Startup))] namespace Recipe01 { public class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } } }
The following lists the important points here:
SignalR 2.0 uses Open Web Interface (OWIN) for .NET as the standard interface between .NET web servers and web applications, enabling a level of indirection and abstraction that keeps your project from directly tying to any specific hosting platform. This is the technical foundation that actually enables SignalR to be hosted from both web applications and traditional .NET processes, as we'll see later.
Every OWIN application must have a
Startup
class that follows specific conventions. In particular, aConfiguration()
method with the signature shown in the preceding code must be made available.The assembly-level attribute
OwinStartup
is there to declare that ourStartup
class will be used to bootstrap every OWIN-based asset contained in all the loaded assemblies; there are other ways to declare the rightStartup
class to load, but we'll see them in the future recipes.Inside the
Configuration()
method, we start up SignalR using an appropriate extension method (MapSignalR()
) made available by the SignalR core inside theOwin
namespace; a call to theMapSignalR()
method will expose an endpoint called/signalr
, which the clients will use to connect to the server.
We're done! Our first SignalR Hub is ready to be called. However, as already mentioned, in order to see it in action, we need a client. Let's build one inside our web application using the JavaScript SignalR client.
Let's add a web page that we'll use as the place to put our basic client to test our Hub. This is where the recipe differs across the different project types. The most natural choices are as follows:
Web form for a Web Forms application: From the Project menu, select Add New Item, click on the Web folder, select the Web Form template (specifying, for example,
index.aspx
as the name), and click on OK.Razor View for an MVC application: Let's first add a default controller named
HomeController
and then a view for itsIndex
default action, which will be calledindex.cshtml
. Please refer to the Appendix A, Creating Web Projects if you want more details about these steps.HTML page for a website: From the Project menu, select Add New Item, click on the Web folder, select the HTML Page template (specifying, for example,
index.html
as the name), and click on OK.
Visual Studio will create the specified file with some basic HTML content. Those files will slightly differ according to the type you picked earlier, but for now we're just interested in the content of the <head>
section, which we'll modify to make it look like the following code:
<script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script src="/signalr/hubs"></script> <script> $(function () { var hub = $.connection.echo; $.connection.hub .start() .done(function () { hub.server.say('Hello SignalR!'); }); }); </script>
We basically kept what was there and then we just added a few <script>
blocks. We'll go into detail about this portion in the Connecting to a Hub from a JavaScript client recipe. So, for any questions you might have about this code, please hold on for a while! The only thing we anticipate here is that the special /signalr/hubs
endpoint does not correspond to any file that you'll find in the project; nevertheless, it's correct and will be explained later on.
We can now launch the application from Visual Studio: a browser window will open, the page will be loaded, and the Say()
method of the EchoHub
class will be executed as soon as the page is completely loaded in the browser. We can prove this by observing the effect of the Trace.WriteLine(message);
line of code on the Output debug window, where the message will be printed.
Let's review the main points of what we just did:
We added a
Hub
class. Any class available in the project that is derived fromHub
is automatically discovered and exposed when SignalR is initialized callingMapSignalR
in theStartup
class.The client page established a connection to our
EchoHub
using the JavaScript SignalR client library.When the connection is ready, we make a remote call to the
Say()
method exposed by ourEchoHub
.SignalR coordinates the two sides using the most appropriate connection strategy (more on that in future recipes), taking into account which is the HTTP server hosting the application and which web browser is used to run the client page; it gives us the feeling of a direct connection towards our server-side Hub, allowing us to call methods on it directly (the line
hub.server.say('Hello SignalR!');
).
SignalR can be considered as a web framework because it's based on web technologies, such as HTTP and HTML5, but it can actually be used in the context of classic standalone processes without any relationship to browsers or web servers. This is possible thanks to the .NET client library for the client part, and to the self-hosting capabilities for the server part. The latter, in particular, is the subject of this recipe. It enables scenarios where the server-side portion of a SignalR application can live inside any hosting process, without requiring it to be an ASP.NET web application. In this recipe, we'll see how to host SignalR inside a simple console application, but any other .NET process would do. This way, we have a chance to use SignalR in scenarios where we do not have a proper web server available, or where thinking about an embedded SignalR makes sense.
Let's create a console application using the following steps:
Navigate to File | New Project.
Navigate to Installed | Visual C# in the dialog box and select the Windows folder.
On the central panel of the dialog box, select Console Application, give it a name (
Recipe02
, in this case), and click on OK.
Visual Studio will add a Program.cs
file containing the startup code for our application to the new project that we just created in Visual Studio 2013. For this recipe, we will add all our code to this file just after the Program
class, whose static Main()
method we'll be filling at the end of the recipe.
We're ready to actually start building our SignalR server. Visual Studio simplifies the process for web applications or websites, offering a series of code templates for Hub
or Startup
classes that we used in the previous recipe. But, for more general Windows applications, those templates are not available, and we'll have to undergo a slightly longer process. First, we'll need to add a reference to SignalR 2.0, which we can be easily found on NuGet, using the following steps:
Select the
Recipe02
project, and under the Project menu, click on the Manage NuGet Packages… entry.From the corresponding dialog box, let's do a search for the online packages using
signalr self host
as a filter condition. We should be presented with a results list like the following:Let's select the Microsoft ASP.NET SignalR Self Host package and then click on the Install button; this action will download and install all the packages we need to proceed with our application.
We are ready to add some code. Let's start with our Hub by opening the
Program.cs
file and adding the following code just outside of the existingProgram
class:[HubName("echo")] public class EchoHub : Hub { public void Say(string message) { Trace.WriteLine(message); } }
In order to compile the previous code, we'll have to add the following
using
directives at the top of the file:using System.Diagnostics; using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs;
The following lists the important points here:
The class
EchoHub
is derived fromHub
, which comes fromMicrosoft.AspNet.SignalR.Hubs
, and makes the server-side SignalR API available to our class.The class is marked with the
HubName
attribute, which allows us to give the Hub a friendly name to be used from the clients; if we don't use theHubName
attribute, the Hub name will be the same as the class name (in this case, it would beEchoHub
).Our Hub contains a method called
Say()
. This is just a sample method we'll use to show how to expose Hub endpoints. On every call, it will just output the value of themessage
parameter in the debugger Output window, or in any trace listener we may want to configure.
Let's proceed with the rest of the code.
Now we need to add a
Startup
class, as shown in the following code, to correctly bootstrap our SignalR Hub:class Startup { public void Configuration(IAppBuilder app) { app.MapSignalR(); } }
The
MapSignalR
call will expose an endpoint called/signalr
that the clients will use to connect to the server. In order to compile the code, we'll have to add the followingusing
directive at the top of the file:using Owin;
We're almost done. We just need to start up everything inside the
Main()
method mentioned earlier, which we now modify to make it look like the following code snippet:static void Main(string[] args) { using (WebApp.Start<Startup>("http://localhost:1968")) { Console.WriteLine("Server running!"); Console.ReadLine(); } }
In order to compile the code, we'll have to add the following
using
directives at the top of the file:using System; using Microsoft.Owin.Hosting;
The following lists the important points here:
By calling
WebApp.Start<Startup>("http://localhost:1968")
, we are telling the self-hosting subsystem that it has to use ourStartup
class to initiate a SignalR endpoint and make it listen to the supplied URL. The chosen port (1968
) is a random one. You could pick any other, provided you check your firewall when deploying your solution.The resulting endpoint will of course expose the SignalR protocol, therefore only connections to it from a SignalR client would make sense and actually work.
When the initialization call has been completed, we print a message and then wait for someone to press Enter; this is important to keep our console application alive. Without it, the process would immediately end and the server would go away.
Our self-hosting process is now ready to be used. When launched, it will wait for clients to connect and call the Say()
method on the EchoHub
Hub. At each call, we would notice a Hello SignalR! message printed on the Output debug window by the Trace.WriteLine(message);
call inside the Say()
method.
We did not write any client code, but in self-hosting scenarios, it's not so common to have any client portion at all. Therefore, we'll end this recipe here. In the Connecting to a Hub from a .NET application recipe at the end of this chapter, we will be writing a standalone .NET client, and we'll be using it to connect to this server.
After having illustrated the two different ways we have to expose a server-side Hub let's now move on and see the client-side code in more detail.
During the Adding a Hub to an ASP.NET project recipe, we quickly used the JavaScript client library in order to demonstrate that our Hub was fully functional, but we did not go much into detail about it because we were concentrating on the server-side code. This recipe will fill this gap and give more clarity on how a JavaScript client is written. However, in order to make it fully functional, we will need a server-side portion; therefore, we'll be adding a basic Hub the same way we did for the Adding a Hub to an ASP.NET project recipe. Any specific detail about how to do it will be skipped because it's just an accessory to the real goal of this recipe, and we will just list the necessary steps. For any further clarification about that part, you can check the Adding a Hub to an ASP.NET project recipe.
Let's create a website where we'll be hosting our client. This is a common task, so we are going to skip the details. If you want more information about this, you can refer to Appendix A, Creating Web Projects at the end of the book.
We're ready to actually start adding what we need to build our SignalR client. We need to use the following steps:
As we did in the Adding a Hub to an ASP.NET project recipe, we'll add a Hub called
EchoHub
and aStartup
class. Here, we'll skip all the related details for brevity. Just make sure that the project ends up containing the same server-side code. These actions will download and add all the SignalR-related references, including the JavaScript client libraries.Let's add a web page to which we'll add our client. From the Project menu, select Add New Item, click on the Web folder, select the HTML Page template (specifying, for example,
index.html
as the name), and click on OK.
Visual Studio will create the specified file with some basic HTML content; let's edit it to make it look like the following:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script src="/signalr/hubs"></script> <script> $(function () { var hub = $.connection.echo; $.connection.hub .start() .done(function () { hub.server.say('Hello SignalR!'); }); }); </script> </head> <body> </body> </html>
We basically kept what was there and just added the highlighted <script>
blocks that you can see in the previous code.
We can now launch the application from Visual Studio; a browser window will open and the index.html
page will be loaded. Then we'll observe the code reaching the Trace.WriteLine(message);
line inside the Say()
method of the EchoHub
class as soon as the page is completely loaded in the browser.
Let's concentrate on our client page. The details are as follows:
The first relevant portion of code are the first two
<script>
blocks, where we referencejquery
andjquery.signalR
as JavaScript libraries. jQuery is necessary because the SignalR JavaScript client is actually a jQuery plugin, as the actual name of the library makes clear.Our libraries are taken from the
/scripts
folder, where they have been placed by one of the NuGet packages installed as soon as we added our Hub. This package is actually called Microsoft ASP.NET SignalR JavaScript Client and can be installed in any ASP.NET application, even if the application does not contain any Hub. We'll see how this can be useful in future recipes, where we will be trying to connect to Hubs hosted in a different web application from the one containing the client.The third
<script>
block refers to a dynamic endpoint (/signalr/hubs
) exposed by the server portion because of theMapSignalR
call from theStartup
class, already explained in the previous recipes. It actually generates JavaScript code on the fly according to the available Hubs. In practice, the JavaScript proxies for our Hubs (in this case, theEchoHub
Hub) are built on the fly by the server-side portion of SignalR as soon as this endpoint is hit, and they're sent to the client as JavaScript source code.The last
<script>
block is where we actually connect to our Hub. Let's dig more into it. The details are as follows:Our code is written inside a classic jQuery
$(...);
call, which actually ensures that our code is called when the page is fully loaded.We first take a reference to our
echo
Hub, which is exposed by the$.connection.echo
property generated by the dynamic endpoint that we just described.Then we call the
start()
method exposed by the$.connection.hub
member, which performs the actual connection to our server.The
start()
call is asynchronous, and we have to make sure it has actually been completed before using any Hub; that's easy becausestart()
returns a promise object containing adone()
method to which we can pass a callback function, where we put our Hub-related code. This way, we are sure that SignalR will call our code when the Hub proxy is fully initialized and ready to be used.Inside our callback function, we can use our Hub instance; in particular, it's the
server
member from which we are able to call any method exposed by the Hub. Thehub.server.say('Hello SignalR!');
line of code will actually call theSay()
method on our server-side Hub.Note that
say
is written in lowercase here. Regardless of the actual name on the server-side Hub, in a JavaScript context, SignalR automatically generates camel case names in order to provide a more idiomatic JavaScript API.
When launching the application from Visual Studio, a browser window will open, the page will be loaded, and the Say()
method of the EchoHub
class will execute as soon as the page is completely loaded.
In the context of the Adding a Hub to a self-hosting application recipe, we already mentioned that SignalR can be used in the context of a generic standalone process, and we detailed how this can be leveraged for the server-side portion of an application. Thanks to the .NET client library, we can apply the same reasoning on the client side, enabling traditional Windows applications to connect to any SignalR server. In this recipe, we'll learn how to use the .NET SignalR client inside a simple console application. For the server portion to connect to, we'll make use of what we did in the Adding a Hub to a self-hosting application recipe, so please make sure you have the code from that recipe ready and fully working before proceeding.
Let's create a console application using the following steps:
Navigate to File | New Project.
Navigate to Installed | Visual C# in the dialog box and select the Windows folder.
On the central panel of the dialog box, select Console Application, give it a name (
Recipe04
, in this case), and click on OK.
Visual Studio will add a Program.cs
file containing the startup code for our application. For this recipe, we will add all our code to this file, which contains the following lines:
namespace Recipe04 { class Program { static void Main(string[] args) { } } }
We're ready to actually start building our SignalR client. Visual Studio simplifies the process for web applications or websites, which are normally supposed to contain both server- and client-side portions; hence, the action of adding a Hub through the corresponding Visual Studio code template actually includes the JavaScript client portion too. When building a purely .NET client, we do not have a specific code template to use, and we have to resort to NuGet to import the appropriate package. This is done using the following steps:
Select the
Recipe04
project, and under the Project menu, click on the Manage NuGet Packages… entry.From the corresponding dialog box, perform a search for the online packages using
signalr client
as the filter expression. We should obtain a results list like the following:Select the Microsoft ASP.NET SignalR .NET Client package and then click on the Install button. This action will download and install all the packages that we need to proceed with our application.
We are ready to add some code. Let's open the
Program.cs
file and modify theMain()
method's body as follows:using System; using Microsoft.AspNet.SignalR.Client; namespace Recipe04 { class Program { static void Main(string[] args) { var url = "http://localhost:1968"; var connection = new HubConnection(url); var hub = connection.CreateHubProxy("echo"); connection.Start().Wait(); hub.Invoke("Say", "Hello SignalR!"); Console.ReadLine(); } } }
Starting from the inside of the
Main()
method, the first line defines the address to which our client will try to connect to, and the second line actually instantiates aconnection
object pointing to that address; our client will expect to find a SignalR server listening at that position.Then we use the
connection
object to create a proxy for theEchoHub
Hub that we used so far when building our servers (the third line). In this recipe, we are using the one that we created in the Adding a Hub to a self-hosting application recipe, so we know from its code that it will be listening on port1968
, and it will expose ourEchoHub
Hub with the friendly nameecho
, which we supply as a parameter to theCreateHubProxy()
method that will provide us with a proxy pointing to it.We are now ready to perform the connection using the
Start()
method. Its return value is atask
-derived object, which means its execution will be asynchronous; indeed, we are not allowed to use a Hub until the connection process has properly completed. That's why in this example we use theWait()
method to block our code until the connection is effectively ready.When we are done with the
Wait()
call, we can safely address any method on our Hub proxy. We know thatEchoHub
exposes aSay()
method, so we call it usingInvoke
, to which we pass the name of the method to call (Say()
) and the list of the expected parameters (in this case, just one for the"Hello SignalR!"
message argument).The
Console.Readline()
method is there to prevent the process from exiting immediately.
That's it. If we now launch the Recipe 02
console application first and then the one we just built in this recipe (either from Visual Studio directly or from a console window), we should see the server application happily printing Hello SignalR!
on the screen because of the call from our client.
Note
Pay attention; you have to keep the application's Recipe02
project open while Recipe04 is running. If you just debug Recipe02
and then stop the debugger to launch Recipe04
, Recipe02
will be killed. There are several ways to achieve the right workflow. One of the simplest is to make Recipe02
the active project, start it without debugging (Ctrl + F5), and then make Recipe04
active and launch it, with or without debugging.
This recipe has completed our first showcase of SignalR features, and it allowed us to understand the basics of how it works and the general structure of any SignalR-based application. We also learned about the different types of hosting we can use and about the two client libraries available out of the box.