Ajden Towfeek

Towfeek Solutions AB

Building real-time web app with SignalR

We just recently had lab days at work which for me basically means that I can play around with some new tech to keep myself up to date. Anywho, one of the things I tried out was SignalR which is a .net library for building real-time, multi-user interactive web applications.

To goal was to build a simple chat, textbook example, shouldn't be any fuzz, right? I started out with an asp.net mvc 3 empty project and installed the EntityFramework, SignalR and knockoutjs nuget packages. Lately I've been using knockoutjs pretty much in all my web projects, I'm a big fan!

PM> Install-Package EntityFramework
PM> Install-Package knockoutjs
PM> Install-Package SignalR

I'm not a big fan of entity framework code first but it was enough for my throw-it-away-when-you're-done requirements. The basic idea is to just create POCOs and decorate the properties with attributes and the db will be generated for you. 

The only entity I want to store is a chat message:

public class Message
    public int MessageId { get; set; }

    [Required, MaxLength(200)]
    public string Text { get; set; }

and the actual database context as 

public class DatabaseContext : DbContext
    public DbSet<Message> Messages { get; set; }

keeping it really simple, no relations at all. And let's not forget to register the initializer in Application_Start.

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DatabaseContext>());

Now to the fun part, SignalR. We simply create a Hub that runs on the server that will be able to invoke methods on our clients.

public class Messages : Hub
    public void GetAll() { ... }
    public bool Add(Message newMessage) { ... Clients.messageAdded(message); ... }

and on our page we only need to 1) create a proxy on the fly, 2) declare a function on the hub so the server can invoke it, 3) call on the add method on the server.

$(function () {
    // proxy created
    this.hub = $.connection.messages;

    // method invoked by the server when a message is added
    this.hub.messageAdded = function (m) { ... };

    // how we send a message to the server
    this.sendMessage = function () { ... this.hub.add(m); ... };

The server-side code is telling all the clients to call the messageAdded() JavaScript function. Mind blowing? We are actually calling the client back from the server by sending the name of the client method to call from the server via our connection. SignalR handles all the connection stuff on both client and server and makes sure the channel stays open and alive.

Screenshot of desktop browser and windows phone emulator browser:

Download the code (793,9KB) for full example.