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:
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:
Recipe02
project, and under the Project menu, click on the Manage NuGet Packages… entry.signalr self host
as a filter condition. We should be presented with a results list like the following:Program.cs
file and adding the following code just outside of the existing Program
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:
EchoHub
is derived from Hub
, which comes from Microsoft.AspNet.SignalR.Hubs
, and makes the server-side SignalR API available to our class.HubName
attribute, which allows us to give the Hub a friendly name to be used from the clients; if we don't use the HubName
attribute, the Hub name will be the same as the class name (in this case, it would be EchoHub
).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 the message
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.
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 following using
directive at the top of the file:
using Owin;
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:
WebApp.Start<Startup>("http://localhost:1968")
, we are telling the self-hosting subsystem that it has to use our Startup
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.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.