Adding a Hub to a self-hosting application
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.
Getting ready
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.
How to do it…
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.
- The class
- 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.