Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

codeA guest post by Samuel Jack, the founder of TruthVine, a start-up that takes the hassle out of sharing audio sermons on church websites. He is also a freelance .Net consultant, working on projects as diverse as Flow, music making software for DJs, to RavenDb, the NoSQL database. He blogs at, and you can follow him at @samuel_d_jack.

In my previous post, I introduced SignalR, Microsoft’s real-time communications library, and showed how to set it up for your project with a very simple example. In this post I will show you how SignalR provides an elegant solution to a common problem: reporting the progress of long-running server operations to web pages.

Let’s start with the client side. First, a simple bit of HTML to set the scene (you’ll notice from the class names that I’m using the new ASP.Net default style sheet, which is supplied by Twitter Bootstrap):

We have a button to launch a job on the server, a progress bar, which is what this whole exercise is about, and a widget to display when the job is done. Both the progress bar and job-completed widget are initially hidden.

Now we need some script to bring that to life. Let’s make that button do something useful:

The button’s main job is to launch an AJAX request to the server. We’ll take a a look at what the server does later on, but for the moment, all you need to know is that it returns a JSON object containing a Job Id. That Job Id is passed to the trackJobProgress method, which is where you see SignalR in action:

As you saw before, Hubs are the key components in SignalR, and the first thing we do here is to get hold of a proxy to the ProgressHub on the server, which gives notifications about job progress. Using that proxy, you register callbacks to handle the various types of notifications, in this case, progressChanged and jobCompleted. These two callbacks do just what you expect. progressChanged updates the progress bar, and jobCompleted flips switches to hide the progress bar and show the completed message.

With the callbacks configured, you can now call $.connection.hub.start() to set up the connection with the server. Along with calling start() you set up a callback, so that you can be notified when the connection has been established. This callback has an important job to do. It uses the hub proxy, this time to invoke a method on the server: hubProxy.server.trackJob(job.JobId). When you invoke trackJob, and send the Job Id the server gave you earlier, the server makes sure that this client only receives notifications about that particular job, and not everything else it might be working on.

That’s how things look from the client’s perspective. Now let’s slide along the wire to see what the server is up to.

Here’s the JobController with its DoJob action:

In the DoJob method you see the another key ingredient of the recipe: asynchrony. When you kick off a long-running operation, you have to hand it off to a background thread. With the job being taken care of, the method is free to return the job’s Id almost immediately to the client, so the client can start tracking it.

Let’s have a look at JobManager:

DoJobAsync is doing a couple of things. First it creates an object to represent the job and allow progress to be reported. Then it stores this Job for future reference (in a ConcurrentDictionary so that updates from multiple threads are handled for us). DoJobAsync‘s main obligation is to launch the work represented by the action on a background thread, which it does simply by calling Task.Factory.StartNew (TaskCreationOptions.LongRunning is a hint to the Task Parallel Library that this operation might take some time, so allocate threads accordingly).

Of most interest to us, though, is what happens in BroadcastJobStatus, because that’s where the server side of SignalR comes into play.

First we have the Hub class, ProgressHub:

The thing to note here is how we are using SignalR’s Groups feature. Every client connecting to a Hub can be assigned to various Groups. When messages are sent they can be targeted to specific Groups. By creating a Group for each Job, we can use this to ensure that clients only hear about the jobs they care about. Thus, when a client calls TrackJob on the server, it gets assigned to the group for that Job. When we broadcast progress messages, we broadcast them just to the group concerned with that Job.

Finally, since the ProgressHub itself has no idea how jobs are progressing, we need to see how code outside of the Hub can send messages from it. Returning to JobManager, here’s the code I didn’t show you before:

Notice that in JobManager‘s constructor we get ahold of a HubContext for ProgressHub. This is what we use to send messages from outside of the Hub class. So, whenever the Job’s progress changes, we can get hold of the appropriate group for the Job and invoke the progressChanged method for all clients in the group just as if we were in the Hub class.


And that wraps it up, giving us an elegant method for a server to report back to its clients while jobs are in progress.

The complete source code for this project is on GitHub, and includes an example of how you can neatly handle the cancellation of jobs too.

Look below for some great SignalR resources from Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

SignalR: Real-time Application Development is a hands-on, step-by-step guide that will take you from the basics of SignalR to more advanced techniques, such as making your application cloud ready and making it scalable. If you want your applications to be enterprise grade then SignalR, together with this book, is the answer.
ASP.NET MVC 4 Mobile App Development helps you to develop next generation applications, while guiding you to deal with the constraints the mobile web places on application development. By the end of the book, you will be well versed with all the aspects of mobile app development. This book also contains a good section on SignalR.
Real World Windows 8 Development is for .NET developers wanting to utilize their existing skills in XAML and C# towards building a Windows 8 application. On the fence about how your C# and .NET skills apply in the new WinRT world? Have a dream application idea that you slowly want to build up? This book is for you. Be sure to also look at the Signal R sections.

Tags: Ajax, Microsoft, open source, server side, SignalR, web pages,

One Response to “Reporting Server-Side Progress to Web Pages with SignalR”

  1. Vincent

    Your code on Github is excellent. There are many progress bar examples online, but none that show the progress for a long running MVC task using a controller and Bootstrap. Thanks very much.

    The cancel is feature is unique (based on about 6 hours of searching for a usable MVC progress bar online).

    The only suggestion I would make would be to add status messages back to the user, eg “Beginning step 1, Beginning step 2, etc” See for example: (Nice bit of code as well, but not MVC)