2013-08-05

Creating a self hosted app in SignalR and connect clients to it

On my previous blog posts, I’ve used a SignalR code hosted on a web server. But we can run a self hosted SignalR code and without a web application at all. On this example, I’m going to show you how to write the same chat application I’ve described here, using a console app.

First, you have to install SignalR Self hosted package using NuGet Package Manager for Visual Studio. At the moment I write this article, the package is in beta (Prerelease). So you have to select “Include Prerelease”.

Following is the code for the self hosted console application

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using System.Collections.Concurrent;

namespace SignalRSelfHosting
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "
http://localhost:8080";

            using (WebApp.Start<Startup>(url))
            {
                Console.WriteLine("Server running on {0}", url);
                Console.ReadLine();
            }
        }
    }

    class Startup
    {
        public void Configuration(IAppBuilder app)
        {

// Turn cross domain on 
var config = new HubConfiguration { EnableCrossDomain = true };

            // This will map out to http://localhost:8080/signalr by default
            app.MapHubs(config);
        }
    }

    public class ChatHub : Hub
    {
        static ConcurrentDictionary<string, string> dictionary = new ConcurrentDictionary<string, string>();

        public void Notify(string name, string id)
        {
            if (dictionary.ContainsKey(name))
            {
                Clients.Caller.differentName();
            }
            else
            {
                dictionary.TryAdd(name, id);

                foreach (KeyValuePair<String, String> entry in dictionary)
                {
                    Clients.Caller.online(entry.Key);
                }

                Clients.Others.enters(name);
            }
        }

        public void Send(string name, string message)
        {
            // Call the broadcastMessage method to update clients.
            Clients.All.broadcastMessage(name, message);
        }

        public void sendToSpecific(string name, string message, string to)
        {
            // Call the broadcastMessage method to update clients.
            Clients.Caller.broadcastMessage(name, message);
            Clients.Client(dictionary[to]).broadcastMessage(name, message);
        }

        public override Task OnDisconnected()
        {
            var name = dictionary.FirstOrDefault(x => x.Value == Context.ConnectionId.ToString());
            string s;
            dictionary.TryRemove(name.Key, out s);
            return Clients.All.disconnected(name.Key);
        }
    }
}

You may note, my ChatHub class is same as I’ve used in the web application. All the methods in my hub class is same.

All you have to do is, run the console application as same as you run the web application project. This will not require a web server like IIS. The console application will use a HTTP listener and OWIN to process the HTTP requests it get. Here I’m using http://localhost:8080 as my server. So my clients should point the hub URL to that.

If we are going to change the sample JavaScript client I’ve show in below blog post,

http://ruchirac.blogspot.com/2013/02/creating-chat-application-in-aspnet.html

I’ve to add the below line at the top of the JavaScript code to tell that, use this URL as the hub connection.

$(function () {
        $.connection.hub.url = “
http://localhost:8080/signalr”;

………………

All the same, in order to point my .NET client applications I’ve described at below blog posts,

Console App - http://ruchirac.blogspot.com/2013/03/connecting-net-client-console.html

Windows Store App - http://ruchirac.blogspot.com/2013/07/connecting-windows-store-app-to-website.html

I have to pass the new URL for self hosted application when I make my hub connection. I can do it like this

var hubConnection = new HubConnection(“http://localhost:8080/signalr”);

So that’s all it take to convert the web hosted SignalR application to a self hosted console application! You don’t need a web server at all!

No comments: