Monday 30 December 2013

Self-Hosting ASP.NET SignalR Using Katana

With the recent release of ASP.NET, Microsoft added a new component, Katana. It is an implementation of OWIN (Open Web Interfaces for .NET) that provides a light weight alternative to create a .NET server quickly without needing any of the ASP.NET components or IIS. The server can be composed anywhere, even on a simple Console based application. For more information on Katana, read the excellent introductory article by Howard Dierking.

The project templates of ASP.NET that come with Visual Studio 2013 have some pieces of Katana also installed, as we saw some of them in my post on Identity system. It is used there to make the identity system available for across all flavours of ASP.NET.

Katana made the process of self-hosting ASP.NET Web API and SignalR very easier with its simple interface. Any Katana based application needs a startup class to kick the things off. We can perform any global configuration in this class. It includes hub route mapping in SignalR or API controller routing in Web API.

Let’s build a simple console-hosted SignalR application using Katana. Create a console application using Visual Studio 2013 and install the following NuGet package on this project:


Install-Package Microsoft.AspNet.SignalR.SelfHost


This package installs all the dependencies required to write and publish a SignalR application on a non-web based environment. Add a new class to the project; name it Startup and add the following code to it:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapSignalR();
    }
}

The configuration method is used comparable to Application_Start event in Global.asax, it gets called at the beginning of the application. As we see, SignalR routes are mapped in the configuration method. We need to start the server in the Main method of the Program class. Add following code to the Main method:
static void Main(string[] args)
{
    string uri = "http://localhost:8080/";

    using (WebApp.Start<Startup>(uri))
    {
        Console.WriteLine("SignalR server started, start sending requests");
        Console.ReadKey();
        Console.WriteLine("Server stopped!");
    }
}

As there is no web server to host our application, we need to specify a port number where the server has to keep running. The generic static method WebApp.Start is called to start the server; it calls the Configuration method defined above. The server would stop once the console application stops running.

Let’s create a boring hello-world kind of hub. Following is a hub that takes name of a person and returns a greeting message with current time stamp:

public class HelloWorldHub : Hub
{
    public void Greet(string name) 
    {
        Console.WriteLine("Got a request from: {0}", name);
        string message= string.Format("Hello, {0}. Greeted at: {1}",name,DateTime.Now.ToString());
        Clients.All.acceptGreeting(message);
    }
}

Run the console application, you should be able to see the following message:

Let’s quickly create a console client to test if the server is able to push messages to the client. Create another console application and add the following NuGet package to it:


Install-Package Microsoft.AspNet.SignalR.Client


Add following code to the Main method:

static void Main(string[] args)
{
    var hubConnection = new HubConnection("http://localhost:8080/");
    var hubProxy = hubConnection.CreateHubProxy("HelloWorldHub");
    hubProxy.On<string>("acceptGreeting", message => {
        Console.WriteLine("Received from server: " + message);
        Console.WriteLine("\n\nPress any key to exit.");
    });

    Console.WriteLine("Establishing connection...");
    hubConnection.Start().Wait();
    Console.WriteLine("Sending request to hub...");
    hubProxy.Invoke("Greet", "Ravi").Wait();

    Console.ReadLine();
    hubConnection.Stop();
}

Run the client application, you should be able to see the following output:



Happy coding!

8 comments:

  1. I just appreciate this blog.Lots of information are here in this blog.Please post more information about the new component katana.

    ReplyDelete
  2. When I try this it just launches IIS as usual.

    ReplyDelete
    Replies
    1. I didn't get any such issues. Can you post some details?

      Delete
  3. I don’t quite get this... Sure it’s cool to be able to self-host an application and it might be nice since if the IIS goes down for any reason... then all your sites goes down... .But if they are self-hosted then they live there own life in their own context....Which I guess is nice... But I still don’t get the pros of this... do I skip alot of unnecessary things in the IIS pipe by using owin which speeds the application up, or… Whats the actual pros? (You don’t need to list all of them if they are many :), but just so I get why you would like to use OWIN and Katana over the IIS)

    ReplyDelete
    Replies
    1. Hi Smith,

      Sorry for the slow reply.

      OWIN and Katana don't replace IIS. IIS is still there to publish enterprise level web applications. Katana can be used in scenarios where you want to publish over HTTP but don't want to go for a full blown web application. An example could be a windows service that updates tables of a Database periodically. Suppose, I want to expose a Web API that serves this data and not do anything else, then I can host a Web API in the same windows service instead of creating a separate web app for doing the same.

      Recently, Microsoft also released a project callled Helios that helps hosting OWIN over IIS without need of System.Web. You can check the introductory blog post here: http://www.asp.net/aspnet/overview/owin-and-katana/an-overview-of-project-katana

      Delete
    2. Thanks ravi...for your valuable information...

      Delete
  4. Very nice discussion..Katana is a flexible set of components for building and hosting OWIN-based web applications & it's really beneficial for Self-Hosting ASP.NET signals.Thank you very much for your precious information.

    ReplyDelete
  5. This is best for the route collection methods.

    ReplyDelete

Note: only a member of this blog may post a comment.