SignalR Realtime Application Cookbook
上QQ阅读APP看书,第一时间看更新

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:

  1. Navigate to File | New Project.
  2. Navigate to Installed | Visual C# in the dialog box and select the Windows folder.
  3. 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:

  1. Select the Recipe02 project, and under the Project menu, click on the Manage NuGet Packages… entry.
  2. 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:
    How to do it…
  3. 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.
  4. 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 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:

    • The class EchoHub is derived from Hub, which comes from Microsoft.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 the HubName attribute, the Hub name will be the same as the class name (in this case, it would be EchoHub).
    • 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 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.

  5. 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 following using directive at the top of the file:

    using Owin;
  6. 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 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.
  • 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.