<img src="1124691/ProjectSampleImage.jpg" style="width: 600px; height: 327px;" />
Introduction
You have a long running task in your application and you want your users to know what's going on while they wait for the process to finish? That's exactly why you would want to use SignalR functionality. You could show progress bar saying "In progress" and remove it when the process is done, but wouldn't it be even better if you could give them more detailed information about the status of the process in progress. It was always complicated to do that in web apps until the introduction of SignalR.
This simple app will show you how you can implement SignalR in your MVC application in a matter of minutes.
Adding SignalR to the Project
First thing you need to do to start working with SignalR is to add it in your project. You can use Nuget Package Manager Console.
Go to: Tools > NuGet Package Manager > Package Manager Console
<img src="1124691/NugetPackageConsole.jpg" style="width: 600px; height: 263px;" />
Insert the following command and press Enter: Install-Package Microsoft.AspNet.SignalR
<img height="173px" src="1124691/SignalR-Installation-Command.jpg" width="582px" />
Visual Studio will install it for you.
After the installation has finished, you can go to your Startup.cs file (which is automatically added in MVC5 project, but if you don't have it, check out this link to see what it is and why you would use it. Startup.cs) and map SignalR to your application.
using Microsoft.Owin;
using Owin;
[assembly: OwinStartupAttribute(typeof(SignalRProgressBarSimpleExample.Startup))]
namespace SignalRProgressBarSimpleExample
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.MapSignalR();
}
}
}
...
Next, we must include some scripts preferably in this order. I've included it in my _Layout.cshtml file.
- jQuery -
@Scripts.Render("~/bundles/jquery")
- MVC project already has Jquery included, but you can include it anyway you want
- Bootstrap - We're using bootstrap to style our web app and to use Modal Popup div to show our progress
- SignalR - jquery.signalR-2.0.2.min.js
- /signalr/hubs"
You can download all of these scripts from my demo project.
Below our added scripts, we add a little bit of JavaScript that we will use to get data from the server.
Starting Connection and Handling Data Sent from Server
$(function () {
var progress = $.connection.progressHub;
console.log(progress);
progress.client.addProgress = function (message, percentage) {
ProgressBarModal("show", message + " " + percentage);
$('#ProgressMessage').width(percentage);
if (percentage == "100%") {
ProgressBarModal();
}
};
$.connection.hub.start().done(function () {
var connectionId = $.connection.hub.id;
console.log(connectionId);
});
});
SignallR Hub
<img height="706px" src="1124691/HubsFolder.jpg" width="321px" />
Next, we create a new folder called Hubs, and create a class called ProgressHub.cs which inherits from Hub
. We must have this class in order for SignalR to communicate between server and client. We don't have to define any method here because in this example we want to send data directly from server. Every other chat tutorial calls the method from client and then sends data back to every other client that is connected at that point.
Our example uses some other method to do some work and then we send the data from outside of the hub.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRProgressBarSimpleExample.Hubs
{
public class ProgressHub : Hub
{
}
}
In our HomeController
, there is a method that we called from button on the client side that does some work and sends data to the client every time it iterates through each item in the loop.
public JsonResult LongRunningProcess()
{
int itemsCount = 100;
for (int i = 0; i <= itemsCount; i++)
{
Thread.Sleep(500);
Functions.SendProgress("Process in progress...", i , itemsCount);
}
return Json("", JsonRequestBehavior.AllowGet);
}
At the end of each task done, we call Functions.SendProgress("Process in progress...", i , itemsCount);
that sends data back to client.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using SignalRProgressBarSimpleExample.Hubs;
namespace SignalRProgressBarSimpleExample.Util
{
public class Functions
{
public static void SendProgress(string progressMessage, int progressCount, int totalItems)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
var percentage = (progressCount * 100) / totalItems;
hubContext.Clients.All.AddProgress(progressMessage, percentage + "%");
}
}
}
hubContext.Clients.All.AddProgress(progressMessage, percentage + "%");
- sends data to all clients connected at that time (for the purpose of this tutorial). See more information about SignalR Clients, Groups...
Points of Interest
After reading many tutorials about implementing SignalR, I decided to make this tutorial (which is my first ever) to help you get started quickly with SignalR. This example is not another chat tutorial, but a progress bar tutorial.
Please fell free to download the sample project and test it...