A simple chat application or playing with ASP.NET SignalR

ASP.NET SignalR has become famous lately. SignalR is a library that makes it simple to add real-time web functionality to applications. But, instead of the name beginning with ASP.NET, SignalR can also be used with console, webforms or WPF applications. This simple chat application uses a console application as a server and webforms for the client. The functionality is simple and very straight forward:

  • Join the server with a freely chosen username
  • Display all users that are active on the server
  • User have the ability to send messages to all other users

To get the latest version of SignalR (SignalR is still under development and not officially released yet), I highly recommend the NuGet plugin for Visual Studio.

SignalR1

The communication of SignalR is organized with so called Hubs. A Hub is a simple class which has methods that can be called from a client. A hub class must be derived from the base class Hub. The ChatHub class has three methods, as seen below:

  • SendMessage() – To send a message to all users
  • Join() – To join the server
  • GetUsers() – To get all active users

All active users holds the server in a static class, called LocalCache.


[HubName("ChatHub")]
public class ChatHub : Hub
{
    public Task SendMessage(string message)
    {
        String formatedMessage = String.Format("{0}: {1}", LocalCache.Users[Context.ConnectionId], message);
 
        return Clients.All.addMessage(formatedMessage);
    }
 
    public Task<Boolean> Join(string username)
    {
        LocalCache.Users.Add(Context.ConnectionId, username);
 
        Clients.Others.addMessage(username + " joined the chat.");
 
        Console.WriteLine(Context.ConnectionId + " (" + username + ") connected.");
 
        return Task.Factory.StartNew(() =>
        {
            return true;
        });
    }
 
    public List<String> GetUsers()
    {
        return LocalCache.Users.Values.ToList<String>();
    }
}

The interesting part in the code above is the context class Clients, which is used to send a message to all clients or to all except the caller of the method. The last one is for the Join method, because the caller already knows that he will join the chat.

To run the server and to start the Hub, it is necessary to start the application and map the Hub to a URL, which can be defined freely. This example uses localhost, port 8080 and the folder chatserver.


class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting server...");
 
        string url = "http://localhost:8080";
 
        using (WebApplication.Start<Startup>(url))
        {
            Console.Clear();
            Console.WriteLine("Server running on {0}", url);
 
            while (true)
            {
                ConsoleKeyInfo ki = Console.ReadKey(true);
                if (ki.Key == ConsoleKey.X)
                {
                    break;
                }
            }
        }
    }
}
 
class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.MapHubs("/chatserver");
    }
}
 
public class LocalCache
{
    public static Dictionary<String, String> Users = new Dictionary<string, string>();
}

That’s it for the server. Now the server can be started.

SignalR2

The client is as simple as the server. The GUI shows the messages, the users and the textbox to enter a message.

SignalR3

The eventHandler Form_Load of the Form1 does most of the necessary work. It sets up a connection to the URL of server and creates a proxy for the hub. After a successful join to the server the client creates a subscription to the addMessage method of the server. The method will be called if the server gets a message from a client. Furthermore a timer is started, which updates the user list every 5 seconds. To call a method on the server the Invoke method of the proxy class must be used, such as shown with the method Join in source code below.


private void Form1_Load(object sender, EventArgs e)
{
    SetStatus("Connecting");
    connection = new HubConnection("http://localhost:8080/chatserver", false);
 
    myHub = connection.CreateHubProxy("ChatHub");
 
    frmLogin login = new frmLogin(myHub);
    login.ShowDialog();
 
    connection.Start().ContinueWith(task => 
        {
            if (task.IsFaulted == false)
            {
                if (connection.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
                {
                    SetStatus("Connected");
 
                    myHub.Invoke("Join", login.Username).ContinueWith(task_join =>
                    {
                        if (task_join.IsFaulted)
                        {
                            MessageBox.Show("Error during joining the server!");
                        }
                        else
                        {
                            Subscription sub = myHub.Subscribe("addMessage");
                            sub.Data += args =>
                            {
                                Message(args[0].ToString());
                            };
                                    
                            UpdateUsers();
 
                            timer1.Enabled = true;
                        }
                    });
                }
                       
            }
 
        });
}

It is as simple as it sounds. The chat server and the client are ready. Of course the source code is more like an example of quick and dirty coding, but it shows the functionality and the opportunities of ASP.NET SignalR very well. As I wrote before, SignalR is still under development, so it is possible that this example won’t work with future versions.

SignalR makes it very, very ease to create communication between server and clients. If you are planning to write a real Chat server, a notification server or anything else with communication, keep an eye on SignalR.

To read more, follow these links:
http://signalr.net/
https://github.com/SignalR

The full example can be found on github: https://github.com/Veloursnebel/SignalRChat/

Advertisements
This entry was posted in ASP.NET, C#, Development and tagged , . Bookmark the permalink.

3 Responses to A simple chat application or playing with ASP.NET SignalR

  1. Pingback: SignalR with Windows Azure Cloud Services | .Kai Blog

  2. Pawan kumar says:

    Nice article o signal r. Used the code sample to learn more. Thanks

  3. adil says:

    Hi,

    I am trying to implement this example in a webrole but I am unable to do so. When I maphub in the global.asax it gives the following error.

    ‘System.Web.Routing.SignalRRouteExtensions.MapHubs(System.Web.Routing.RouteCollection, string, Microsoft.AspNet.SignalR.HubConfiguration)’ is obsolete: ‘Use IAppBuilder.MapSignalR in an Owin Startup class.

    Can you please guide how do I get it to work.

    Plus where do i add the chat hub class in webrole. I just added a class in the webrole. Would that be sufficient?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s