Click here to Skip to main content
14,937,005 members
Articles / Web Development / ASP.NET
Tip/Trick
Posted 22 Oct 2013

Stats

87.2K views
6.9K downloads
68 bookmarked

Real-time Notifications with SignalR

Rate me:
Please Sign up or sign in to vote.
4.86/5 (27 votes)
27 Oct 2013CPOL3 min read
Notify the users on the progress of time consuming operations in real-time

Introduction

Sometimes, server side operations take time. It's not really user friendly to have users pressing a button and waiting 30 seconds for some operation to be executed, with the only progress information being a spinning wheel.

If you have server side operations that are time consuming and you would like your users to get insight into what's going on in the server in real-time, this tip is for you.

I will show how you can use SignalR 2.0 to send messages from the server to the client while a process is running in the server. The result is a notification bar that is displayed to the user showing the progress happening in the server.

Disclaimer

The fact that you can use such technique doesn't mean you should start using it everywhere. You should always strive to optimize performance. As an example, if you have a database query that is slow, you should try to optimize it first and, if it's really an expensive operation that you cannot improve, you can use such a technique to make your users more informed about the operation in progress.

Using the Code

For creating the sample application I describe below I used Visual Studio 2013, jQuery 1.10, SignalR 2.0 and noty 2.1. 

First of all, we need to add SignalR to the web application. There are several ways to do this, the simplest being right-clicking in your project, Manage NuGet packages, search Online for signalr and selecting to install Microsoft ASP.NET SignalR.

We are going to use a notification jQuery plugin that provides nice out-of-the-box notifications. Still in NuGet's package management window, search for "noty". Select and install the package named jQuery Notification Plugin.

Next, we add to the project a OWIN Startup class.

Image 1

Add the following line to the Configuration method of the new Startup class:

C#
app.MapSignalR();   

Next, we are going to add a SignalR hub. For this, add a new SignalR Hub Class (v2) item to your project.

Image 2

This is the class that does the server side processing. In the example I attach to this article, I have the class defined as follows:

C#
public class RealtimeNotifierHub : Hub
{
    public int recordsToBeProcessed = 100000;
 
    public void DoLongOperation()
    {
        for (int record = 0; record <= recordsToBeProcessed; record++)
        {
            if (ShouldNotifyClient(record))
            {
                Clients.Caller.sendMessage(string.Format
                ("Processing item {0} of {1}", record, recordsToBeProcessed));
                Thread.Sleep(10);
            }
        }
    }
 
    private static bool ShouldNotifyClient(int record)
    {
        return record % 10 == 0;
    }
}      

At this point, our server is ready. We have a method called DoLongOperation that is called from the client side. This method simulates a long running operation with 100.000 iterations and, at every 10 iterations, notifies the client of the current status. The Thread.Sleep call was introduced to slow down the server, otherwise the for loop runs so fast that the notification bar wouldn't be needed.

Next, we have to prepare the client. Create a new HTML page (or use the page where you want to show the notifications).

HTML
<!DOCTYPE html>
<html>
<head>
    <title>Real-time notifier</title>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    
    <!-- Import the noty scripts -->
    <script src="Scripts/noty/jquery.noty.js"></script>
    <script src="Scripts/noty/layouts/top.js"></script>
    <script src="Scripts/noty/themes/default.js"></script>
    
    <!-- Import the SignalR scripts -->
    <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
    <script src="/signalr/hubs"></script>
</head>
<body>
    <div style="margin-top: 100px;">
        <!-- This button will trigger the time consuming operation -->
        <input type="button" id="mybutton" 
        value="Call a time consuming server side operation" />
    </div>
    <script type="text/javascript">
 
        $(function () {
            // Initialize the connection to the server
            var realtimeNotifier = $.connection.realtimeNotifierHub;
            
            // Preparing a client side function 
            // called sendMessage that will be called from the server side
            realtimeNotifier.client.sendMessage = function (message) {
                showOrUpdateSuccessMessage(message, false);
            };
 
            // Establish the connection to the server. When done, sets the click of the button
            $.connection.hub.start().done(function () {
                $('#mybutton').click(function () {
                    // When the button is clicked, 
                    // call the method DoLongOperation defined in the Hub
                    realtimeNotifier.server.doLongOperation();
                });
            });
        });
    </script>
    <script type="text/javascript">
        // Helper code that updates the noty notification bar
        var n;
        function showOrUpdateSuccessMessage(message, timeout) {
            if (n == null) {
                n = noty({ text: message, type: 'success', timeout: timeout, maxVisible: 1 });
            }
            else {
                n.setText(message);
            }
        }
    </script>
</body>
</html>   

The example above does several basic things:

  • Establishes the connection from the client to the server
  • Declares a client side function that will be called by the server
  • Calls the server's method that performs the time consuming operation
  • Updates the noty notification bar.

This is how it looks like when it's running:

Image 3

Feel free to use this code. I have attached a Visual Studio 2013 solution that should just work.

If you have any questions, I'll be happy to answer them.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

GustavoMartins
Software Developer Hinttech BV
Netherlands Netherlands
I'm a Portuguese software engineer living in The Netherlands and working for HintTech BV

Comments and Discussions

 
Questionvs 2015 updates ? Pin
kiquenet.com6-Jun-16 10:43
professionalkiquenet.com6-Jun-16 10:43 
Question$.connection.RealtimeNotifierHub undefined Pin
Habeeb Matrix11-Jan-16 19:00
professionalHabeeb Matrix11-Jan-16 19:00 
AnswerRe: $.connection.RealtimeNotifierHub undefined Pin
Habeeb Matrix11-Jan-16 19:10
professionalHabeeb Matrix11-Jan-16 19:10 
GeneralGreat Pin
karlta0519-Jan-15 20:23
Memberkarlta0519-Jan-15 20:23 
GeneralsignalR Pin
thami3628-May-14 23:20
Memberthami3628-May-14 23:20 
GeneralThanks! Pin
Patrick Kalkman18-Nov-13 1:13
MemberPatrick Kalkman18-Nov-13 1:13 
GeneralMy vote of 5 Pin
M Rayhan27-Oct-13 20:15
MemberM Rayhan27-Oct-13 20:15 
QuestionWeird javascript reference Pin
Guus Beltman27-Oct-13 0:28
MemberGuus Beltman27-Oct-13 0:28 
AnswerRe: Weird javascript reference Pin
GustavoMartins27-Oct-13 4:12
professionalGustavoMartins27-Oct-13 4:12 
GeneralTimely information Pin
David Steverson24-Oct-13 7:53
professionalDavid Steverson24-Oct-13 7:53 
Thank you for this, I just recently learned of Signal R and happen to now have a need for it, this article is a great starting point.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.