Skip to content

Getting up and running with SignalR

andrerpena edited this page Sep 20, 2013 · 7 revisions

The server

As I said, ChatJS only works out of the box with ASP.NET with SignalR, so, this manual will be focused in this scenario. Everything that I'll explain here is implemented already in the demo application available in the ChatJS package. It's highly recommended that will download that before continuing with this manual. First thing to do is to download SignalR if you haven't already. To do so, in Visual Studio, select the Tools menu, and then Library Package Manager and then select Package Manager console. Now type in the following line:

Install-Package Microsoft.AspNet.SignalR

This will install all the packages needed to run SignalR. Now let's set up the code. First, go to your HttpApplication class and put this in the Application_Start method:

protected void Application_Start()
{
    //...
    // add this line:
    RouteTable.Routes.MapHubs();
}

This will map the routes needed to make the server accessible to the client. Next, you need to add the necessary scripts in your Views, preferably the layout. Add the following lines:

<script src="/Scripts/jquery.signalR-1.1.0.min.js"></script>
<script src="/signalr/hubs" type="text/javascript"></script>

The first line adds a script that has been added to your product when you installed the SignalR Nuget package. The second one will expose server code to the client. Each public server SignalR function will have an equivalent client code at $.connection.[your_hub_name].

Now you need a Hub. A Hub is a high level SignalR class that allows for seemless client/server communication. Once the Hub is registed, it's possible for the client to call a Hub public method and it's possible for the Hub to call a client method. Your new Hub needs to enherit from the Hub class and implement this interface. The IChatHub interface forces you to implement methods in the server that are going to be called from the client adapter. While implementing your own ChatHub, you should consider the sample implementation. Even though it's not meant to be used in production, it gives you a good idea of what to do in each method. All you have to do is to replace the code that deals with the logged user, as well as the code that persists and queries chat messages. You are probably using some database for that.

The client

ChatJS has two JavaScript files: jquery.chatjs.signalradapter.js and jquery.chatjs.js. The first one is responsible for the client/server communication. ChatJs itself doesn't know how to communicate to the server, it needs an adapter. If you are using SignalR, you can use the existing adapter without changing anything. If you are implementing your own long polling, for instance, you could create a jquery.chatjs.longpolling.js adapter. As you can see in this code, the client adapter has two roles: The first one is to expose client functions that are callable from the server. Here is an example:

_this.hub = $.connection.chatHub;
_this.hub.client.sendMessage = function (message) {
    chat.client.sendMessage(message);
};

This is code is implementing a client method called sendMessage that is callable from the server. Every function in the $.connection.chatHub object is called from the server. If we weren't using SignalR, we could implement a long polling in the client that calls particular functions based on a parameter the server returns from the long polling. That would be similar. Back to SignalR, just so you're clear, here an example of server code calling this function from within ChatHub (C#):

this.Clients.Client(connectionId).sendMessage(this.GetChatMessage(dbChatMessage, clientGuid));

In this example, this.Clients is the list of client connections. You you're calling a client you must specify which one. If you are sending a message to the user which the Id is 19, for instance, you have to manually track which client connections correspond to the user 19. Yes, there's more than one, because the user Id may have 3 browser tabs opened with the same session, so each user has a list of connections. In the case of ChatHub, the connections are tracked using a Dictionary<string, Dictionary<int, List<string>>>. The outer dictionary is to store rooms and the internal one is to keep track of what connections correspond to what user. They dictionary keys are respectively the room id and the user id.

Now back to the client. The second role of the adapter is to expose a means for the plug-in to contact the server. Intead of requesting the server directly, the plug-in will will call the adapter everytime it needs something. All methods in the adapter that have the role of calling the server are under the server object. Example:

_this.server.sendMessage = function (otherUserId, messageText, clientGuid, done) {
    _this.hub.server.sendMessage(otherUserId, messageText, clientGuid).done(function (result) {
        if (done)
            done(result);
    });
};

When ChatJS has to send a message, it will call this function in the adapter. If we weren't using SignalR, we could simply make regular HttpRequests to call the server. That would be the same.

Now, about the jquery.chatjs.js itself. There's not much to be done and it hasn't many options. The complete usage is like this:

$.chat({
    // your user information
    user: {
        Id: 3,
        Name: 'John Silver',
        ProfilePictureUrl: 'http://www.foo.com/avatar/123'
    },
    // text displayed when the other user is typing
    typingText: ' is typing...',
    // the title for the user's list window
    titleText: 'ChatJs demo chat',
    // text displayed when there's no other users in the room
    emptyRoomText: "There's no one around here.",
    // the adapter you are using
    adapter: new SignalRAdapter()
});

Related resources: