Real time communication with signalR

If you need realtime communication and don’t want to use long polling ajax calls for example for an game or a chat and also want fallback if WebSockets not is supported, signalR is a good library. This is a short tutorial on how to use signalR in an ASP.NET MVC application.

If you want to use a WebSocket connection if it is supported by the client you need to use IIS8 and enable the WebSocket Protocol, read this post for a step by step guide.

If websocket is not supported, signalR has fallback to server side events and ajax long polling, so web browsers without support for websockets can also use signalR.

Add signalR libraries

The easiest way to add signalR to your web application is to use NuGet. It will add the assemblies and javascript libraries needed to the web project.

Install-Package Microsoft.AspNet.SignalR

Server side

First you need to set “aspnet:UseTaskFriendlySynchronizationContext” to true in settings in your Web.config if you want to use websocket.

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>

Next step is to create a new class that inherits from PersistentConnection

public class MyConnection : PersistentConnection
{
}

In this new class you can override the methods OnConnected, OnReceived and OnDisconnected.

OnConnected
This method is called when a client connecting. Here can you for an example add users to users online lists.

OnReceived
This method is called when a message from the client is received, you send it further to your buisness logic or an other user (or users).

OnDisconnected
This method is called when a client disconnecting. Here can you for an example remove users from users online lists.

In my example I have a player object that handles logic for a player. To keep the player object alive I add a static dictionary with the connection id as key.

public class MyConnection : PersistentConnection
{
        private static Dictionary<string, Player> _players;
 
        protected override System.Threading.Tasks.Task OnConnected(IRequest request, string connectionId)
        {
            if (_players == null)
            {
                _players = new Dictionary<string, Player>;();
            }
 
            var player = new Player();
 
            _players.Add(connectionId, player);
 
            player.SomethingHappend += (sender, args) =&gt; Connection.Send(connectionId, "Hello!");
 
            return base.OnConnected(request, connectionId);
        }
 
        protected override System.Threading.Tasks.Task OnReceived(IRequest request, string connectionId, string data)
        {
            var player = _players[connectionId];
            player.DoStuff(data);
 
            return base.OnReceived(request, connectionId, data);
        }
 
        protected override System.Threading.Tasks.Task OnDisconnected(IRequest request, string connectionId)
        {
            var player = _players[connectionId];
 
            player.Dispose();
 
            return base.OnDisconnected(request, connectionId);
}
        }

Before you can start using your signalR server you need to map a route in Global.asax.cs. Add the route to the Application_Start method before other route mappings.

protected void Application_Start()
{
            RouteTable.Routes.MapConnection<MyConnection>("connection", "/my");
}

The url to the signalR server will now be http://pageurl/connection/my.

Connection.Send(connectionId,message) sending a message to a specific user using the connection id. It make’s it possible to have communications between two clients.

If you want to send a message to all connected users you should use Connection.Broadcast(message).

Client side

Start to add a reference to the signalR javascript library.

Connect
To connect to the signalR server use the relative url that you created with the mapping in Global.asax.cs.
If you want to know when the connection has successfully established use callback on the start function.
Use the stateChanged event if you want to know when states changes on the connection. For example you can use it for to tell users that connection has been lost.

The connection has four states:

  • Connecting
  • Connected
  • Reconnecting
  • Disconnected
var myConnection = $.connection('/connection/my');
myConnection.start(callback);
        myConnection.stateChanged(function (change) {
            if (change.newState === $.signalR.connectionState.connected) {
 
            }
        });

Send message
To send a message use the send(message) method on the connection object.

myConnection.Send(message);

Received

myConnection.received(function (message) {
     //Handle the message here.
});

That is all. It is not harder than that to use real time communication in your web application.

Enable WebSocket Protocol in IIS

If you want to use WebSockets with IIS8 you need to enabled it. This step by step guide will show you how to enable WebSocket Protocol on Windows 8 and Windows Server 2012.

Enable WebSocket Protocol in Windows 8

  1. Open “Control Panel
  2. Open “Turn Windows features on or off
  3. Expand “Internet Information Services”
  4. Expand “World Wide Web Services”
  5. Expand “Application Development Features
  6. Check WebSocket Protocol and click “OK”

Enable WebSocket Protocol

Enable WebSocket Protocol in Windows 2012 server

  1. Open “Server Manager”
  2. Click on “Manage” in the right corner”
  3. Click “Add Roles and Feature”
  4. Go to “Installation Type in the Wizard”
  5. Select “Role-based or feature installation and click “Next”
  6. Go to “Server Roles”
  7. Expand “Web Server(IIS)”
  8. Expand “Web Server”
  9. Expand “Application Development”
  10. Check WebSocket Protocol and click “Next”
  11. Click on “Install”

Enable WebSocket Protocol Windows Server2012

If you running a web role in Windows Azure you don’t need to activate it, it’s already done!