Having the Server Call the Client with SignalR

Microsoft’s latest technology for creating Web Services–SignalR–addresses an interesting problem in creating modern applications: two-way communication. The whole point of Web Services is that the server ”knows” something that the client does not. To get that information the client calls the service to get that information. However, in a volatile environment (where data on the server frequently changes) with a long running client (where the client stays connected to the server while that volatile data changes) and critical information (the client wants to stay up-to-date with the server’s changes) it may be necessary for the client to be updated as data changes on the server. With the original design of Web Services that was only possible through ”long polling”: the client keeps calling the service to ask ”Has anything changed?” That’s terrifically inefficient in two ways: Either the client waits a long time between checking so that, when the client does get the information, the data is stale and/or out-of-date; The client checks frequently so that the server is battered with requests when, most time, nothing has changed. The right answer is to have the server call the client when something changes. The trick is to find an interoperable, industry standard way to do that.

There are a couple of HTML5 solutions to this problem that stay interoperable: using server-side events or WebSockets, for instance. But the problem with HTML5 is that not all modern browsers support all of the various HTML5 specs…and, anyway, not all users are using modern browsers. SignalR provides a single interface for letting the server call the client and does that by concealing from the developer how this magic is achieved: SignalR will use WebSockets if the browser supports it but (in the absence of WebSockets) will revert to other technologies, including long polling if necessary.

And, before I go any further, I should point out that SignalR is still only in ”release candidate” mode. It’s possible that Microsoft might never release a final version of this technology (as happened with Upshot) or, better yet, might roll this into some other technology (the ASP.NET Web API would be my choice, as covered in Learning Tree’s 2601 course, Introduction to WCF and Web API Services).

Accepting and Sending Messages at the Server

A simple SignalR application consists of a server-side hub that can receive requests from clients (JavaScript or otherwise) and send messages to those clients. On the server you just need to register that you’re using SignalR and the SignalR server-side component will route all incoming SignalR requests to methods on ”hubs” that you define. Similarly, any messages generated by your hubs will be sent out to clients that have connected to the hub. In the browser, you need to establish a connection to a server-side hub, calls methods on the hubs you’re connected to, and define client-side functions for the server-side hub to use when sending out messages.  This post will start to demonstrate  how to create a simple broadcast application: all messages sent from any browser-based client are sent to all other browser-based clients. In the following posts, I’ll build on this to show how to accept messages from non-JavaScript clients and how to handle communication with individual clients. I’ll do all of this in an ASP.NET WebForms project but nothing important would change in, for instance, an ASP.NET MVC project.

The first step is to use NuGet to add the SignalR package to your project. Since this is pre-release software you’ll need, in the NuGet Manager dialog, to  set the top-left dropdown list to ”Include Prerelease.” After adding the ”Microsoft ASP.NET SignalR” package, you’ll also need to add the JSON2 package. Since SignalR is implemented as a jQuery add-in you’ll need ensure that you have some version of the jQuery library in your project.

Your next step is to add a server-side SignalR hub to process requests from clients. A hub is a class that inherits from Microsoft.AspNet.SignalR.Hub–do not put this class in the App_Code folder of an ASP.NET project (the client can’t find a class in the App_Code folder). In your hub you need, at the very least, a method that clients can call in order to pass data to the hub. For this case study, I’ll use a method that accepts a single parameter from the client–a text string–and sends that text string to all connected clients. In real life, of course, the method would presumably do some processing on the incoming message and might select which clients are to get the message–tune into later posts for how to do that. Later posts will also use more complex objects than a text string. In this server-side method,  you’ll use SignalR’s HubConnectionContext object which you can retrieve fro the Clients property of you hub class. The HubConnectionContext object’s All property lets you work with all the connected Clients to call a JavaScript function (in browsers) or a lambda expression (in .NET applications) on the clients.

The following code defines a method (which I’ve called ReceiveMessage) in a hub (called MessageHub) that clients can call to send a message to all other clients. The method then calls a function (called acceptMessage) on all the all connected clients (since this method name is one you define, you won’t get any IntelliSense support when you type the function name in):

Imports System
Imports System.Web
Imports Microsoft.AspNet.SignalR

Public Class MessageHub
    Inherits Hub

    Public Sub ReceiveMessage(Message As String)
        Me.Clients.All.acceptMessage(Message)
    End Sub

End Class

To get messages routed to the hubs in your application, you need to register your hubs with SignalR. That requires a single line in your Application_Start method in your Global.asax file (for ASP.NET) or wherever you define your routing rules (in ASP.NET MVC). You’ll need to add an imports statement for System.Web.Routing to make this code work:

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        RouteTable.Routes.MapHubs()
End Sub

My next post will look at what’s required in a JavaScript client to accept this message (and how to avoid sending the message to all clients).

Peter Vogel

Type to search blog.learningtree.com

Do you mean "" ?

Sorry, no results were found for your query.

Please check your spelling and try your search again.