Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

SignalR: ASP.NET Way of Socket Programming

0.00/5 (No votes)
14 Aug 2015 1  
What is SignalR? How do you SignalR and jQuery your way to real-time programming?

Introduction

If you have been following the rapid change of web/mobile development landscape, or if you are in the midst of it, you are probably befuddled / amused / amazed by the constant swirling of new terms/buzzwords.

Ok, quiz time.

What is MEAN? M-E-A-N, stands for Mongo db, Express, Angular js, node js.

What is Gulp, Grunt, React js? Tell me about Ionic framework?

Well, if you know all the above by heart, you are a guru, guru of gurus! You get 1000 stack-overflow up votes!

If you know all the above by heart, you might be (un)consciously biased against Microsoft-based technologies. Well, this is not a golden age for Microsoft anymore.

Quiz again.

Question: What is SignalR? What is in common between SignalR and Node js?

Answer: SignalR is Microsoft ASP.NET way of doing socket programming, “a library for developers to add real-time web functionality to their applications. Real-time web functionality is the ability to have server-side code push content to the connected clients as it happens, in real-time.”

This is what it is in common with node js, node js lets you do real time socket programming too.

Ok, What Really is SignalR Socket Programming?

For a long time, for client-server communications using JavaScript, we use AJAX with http protocol. So a client (e.g., a web browser) sends a request to a web server, and web server sends back data. Each request initiates a connection to a particular port (80, 8080) on a server. Upon the completion of each request, the connection is closed.

Now for web socket protocol, client and server still needs to establish a connection, however, once the connection is established, client and server can pass message back and forth without having to reestablish a new connection.

If I’d explain this to a 6-year-old kid, I would like to explain it this way:

Let’s say your dad is working on the house, he finds that he needs one special tool which your friend’s dad just has. Your friend lives right next door. So your dad calls your friend’s dad, goes to his house and borrows the tool. Now the door is closed. Next time your dad needs to return the tool, he needs to call again.

The above is an http protocol. Your dad initiates a request; the neighbor provides the “data”/tool. Upon which, the connection is closed.

Now, you want to play with your friend, your friend has a lot of toys. You both get the permissions from your parents. Your friend keeps the door open; you just go in and out of his house to fetch whatever you need. Neither of you have to ask for the permission again during this play time.

You might call it a web socket protocol. Once you and your friend established the connection, you and your friend can start to communication, give and take, without any further needs for permissions, knocking on the door, etc.

How to Use SignalR?

For the following sample app, we will load a list of tasks and display it using a jQuery data table. After which, we will update the status of those tasks in real time (simulated). You can check out the full code here.

First thing first, let’s set up the project and add SignalR through nuget.

Let’s go ahead to create a brand new project.

  1. In Visual Studio, create an ASP.NET Web Application.

  2. Please select Empty as your template.

  3. Let Visual Studio crunch out your web application.
  4. In the solution explorer, right click your solution, then click “Manage NuGet Packages for solutions”, search SignalR, then install Microsoft ASP.NET SignalR.

With that, it should install all SignalR required components.

Please make sure you install json .NET as well.

All right, with all that installation out of way, we can go straight to business, create a hub and set up our client side.

Wait a minute, what is a hub?

So a hub is to SignalR as a controller to ASP.NET MVC API. A hub is a server side class that contains various methods your client side code can call. A hub can directly return data to client side or it can push the data to client side when it becomes available.

It might not make sense yet, but let’s carry on.

Let’s create a hub named TaskHub that inherits the SignalR.hub class.

Please note I also created a taskService that does the actual dirty work. My taskHub acts as the interface point between the client and server.

Please checkout TaskService code.

[HubName("taskHub")]
 public class Taskhub : Hub
 {
     private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(1000);
     private static int currentId = 0;
     private Timer _timer;

     public List<faketask> GetTasks()
     {
         return new TaskService().GetAllTasks();
     }

     public void UpdateTasks()
     {
         _timer = new Timer(UpdateTaskStatus, null, _updateInterval, _updateInterval);
     }

     private void UpdateTaskStatus(Object state)
     {
         var tS = new TaskService();
         var task = tS.UpdateTask(currentId%10);
         currentId++;
         Clients.All.updateTaskStatus(task);
     }
 }

So in my TaskHub, I have 2 methods, one is to get all tasks and return to client right away.

public List<faketask> GetTasks()
    {
        return new TaskService().GetAllTasks();
    }

The other is to periodically update the task status one by one and notify all clients that are connected to the hub with this line:

Clients.All.updateTaskStatus(task);

Let's say how client side initiates the connection, sets up a method for a hub to call and calls a hub method.

Let's set up a simple HTML page with a couple of bare-minimum controls: a button that calls for update status, a jQuery datatable that displays all of the tasks. Easy, peasy? Now pay a little attention to the bottom, the set of JavaScript files we need to include:

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

Well, jQuery is jQuery. jQuery.signalR is the SignalR JavaScript client in the form of jquery plugin, the third one signalR/hubs is generated hub proxy.

(Note: Unfortunately, SignalR is completely dependent on jQuery. There has been a community outcry for its independence (from jQuery) and Microsoft team did half-heartedly promise to make it happen 2 years ago, it is not a reality yet.

Well, for this sample app, it is not really an issue. But for non-jQuery folks, it is actually a pain. For example, I would love not to have to include jQuery in my Ext js application.)

Once we have the necessary JavaScript library files included, we shall set up our own JavaScript to make use of all of the signalR goodies.

First all, we start the connection, after which we all our own init function, which calls up our server side hub method to produce a list of tasks and use our datatable to display it.

// Start the connection
$.connection.hub.start()
            .then(init);

function init() {
        return taskHub.server.getTasks().done(function (data) {
        //handle data right here.
    });
}

Notice how on the server side, the hub is calling up the client directly, and on the client side, JavaScript is ringing up on the server directly as well. There are 2 ways for the clients to receive and act on the data sent from hubs. If the hub is able to send back the data right away, you can just specify your callback function in done.

Yep, you guessed it right. This is exactly the as the jQuery ajax done.

$.ajax({
        url: "http://fiddle.jshell.net/favicon.png",
    }).done(function( data ) {
});

However if your server/hub needs to consistently push data to client side, or it simply needs to run asynchronously, the hub can return void, in the same time, opt to notify client by calling a JavaScript function directly.

Clients.All.updateTaskStatus(task);

Of course, the client side will serve up the method as in the following:

// Add client-side hub methods that the server will call
$.extend(taskHub.client, {
    updateTaskStatus: function (task) {
     }
});

Ok, that is pretty much all of the code that needed for this tiny sample signalR applications.

To run it, hit F5 and hopefully you will see the following:

When you click update, you will see that miraculously, the tasks are done and update in every second or so.

Or, you will see errors.

When Things Go Wrong …

There are a few common errors you may encounter for a SignalR application.

  1. signalr/hubs not generated

    When you do not get data, you open up your developer tool, you may error messages such as signalr/hubs not generated.

    Cause / Solution:

    Normally, it simply means the path you specified for the dynamically generated proxy js is not correct. It generally should be at the application root. For ASP.NET MVC 4 or 5 Razor view. Or just inspect your application root.

    <script src="~/signalr/hubs"></script>
  2. No assembly found containing an OwinStartupAttribute

    Stackoverflow has a few QA with regarding to this error. There is a full article regarding this too.

    Basically, you need to make sure you have a startup class that has OwinStartup attribute:

    [assembly: OwinStartup(typeof(StartupDemo.TestStartup))]
    

    Or specify it in the appsettings:

    <appSettings>
      <add key="owin:appStartup" value="StartupDemo.ProductionStartup" />
    </appSettings>
    

    As a matter of fact, if you allow yourself to be a little patient, you can find that Microsoft has quite a lot of information in their SignalR learning section.

Parting Words

Well, like any new technologies, you may find various inconveniences of learning and annoyance of failing to do the basics when you just started, you may crave for the comfort of working with a familiar technology. With SignalR, it may especially be the case.

However, stick around a bit, you may eventually start to like it. It could be your life line, especially when your applications need that real time injection of energy, which is, in this mobile-everywhere-for-everything world, every application.

Note

The complete code can be downloaded or cloned at Github.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here