Real Time Web with SignalR and ASP.NET MVC

This afternoon I was thinking about an app where users will be notified in real time. Some suggestions were raised but at the moment I think only Node.JS and SignalR are the most viable candidate for this scenario. For this post, since I am going to use ASP.NET MVC, I will use SignalR which is native to .NET.

Okay, for those who are not familiar yet with SignalR. According to its site, it is a new library for ASP.NET developers that makes it incredibly simple to add real-time web functionality to your applications. For me, basically, it is the most convenient way in notifying the client that something happened from the server in real time. No need for work around or any sort.

Now, time for the development.

1. First we need to get a reference of SignalR from Nuget. You can also get it from Github. Or download it as zip and add it as reference. But if you are new, I would suggest using nuget.

– Install-Package Microsoft.AspNet.SignalR

SignalR_Nuget

2. Once you have it installed. Let’s create  a Hub. A SignalR Hub enables you to make remote procedure calls (RPCs) from a server to connected clients and from clients to the server.

– First we need to add a folder to our web project called Hubs.

– Then create a class called CustomerHub. Below is how it should look like. I intentionally made it empty since it just acts like a fake hub. All the crud operation happens in the actionresult and you will find out how i called the client method from the actionresult once you finished reading this post.

using Microsoft.AspNet.SignalR;

namespace CustomerSite.Hubs
{
    public class CustomerHub : Hub
    {
        
    }
}

– Then another important part is to add the startup class which does all the mapping.

using Owin;
using Microsoft.Owin;
[assembly: OwinStartup(typeof(CustomerSite.Hubs.Startup))]
namespace CustomerSite.Hubs
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Any connection or hub wire up and configuration should go here
            app.MapSignalR();
        }
    }
}

3. Now lets get back to our view.

– Add a reference to SignalRJS.

<script src=”~/Scripts/jquery.signalR-2.1.2.js”></script>

– Set a reference to the available hubs that we created, in this case the CustomerHub that we created as shown below.

<script src=”/signalr/hubs”></script>

– This is how my Layout looks like.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Realtime Web with SignalR</title>
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="~/Scripts/modernizr-2.6.2.js"></script>
    @RenderSection("styles", false)
</head>
<body>
    <div class="container body-content">
        @RenderBody()
    </div>

    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
    <script src="~/Scripts/knockout.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.2.js"></script>
    <script src="/signalr/hubs"></script>
    @RenderSection("scripts", false)
</body>
</html>

4. The client side SignalR registration with knockout.
-> self.hub = $.connection.customerHub; //tells the hub object to point to customerhub on the server.
-> self.hub.client.getCustomers = function () { //is a method that will be called from the server.
self.loadCustomers();
}
-> $.connection.hub.start(); // the client side listener

function AppViewModel() {
    var self = this;

    self.hub = $.connection.customerHub;

    self.hub.client.getCustomers = function () {
        self.loadCustomers();
    }

    $.connection.hub.start();
    
    ... //Code removed here just for this post.

    //A function for loading the customer view via ajax.
    self.loadCustomers = function () {
        $.ajax({
            url: '/Home/CustomerList',
            success: function (data) {
                $("#customerlist").html(data);
            }
        });
    };

    //The function for updating and adding a customer.
    self.submitForm = function () {
        var url = '/Home/SaveCustomer';
        if (self.isEdit()) {
            url = '/Home/UpdateCustomer';
        } 
        $.ajax({
            url: url,
            data: {
                firstName: self.firstName(),
                lastName: self.lastName(),
                address: self.address(),
                phone: self.phone(),
                creditLimit: self.creditLimit(),
                customerSince: self.customerSince(),
                id: self.customerId()
            },
            success: function (data) {
                if (String(data.saved) == 'true') {
                    self.formVisible(false);
                    //self.loadCustomers();
                }
            }
        });
    };
}
ko.applyBindings(new AppViewModel());

5. For the server side to client interaction via ActionResult.

public ActionResult SaveCustomer([Bind(Exclude = "Id")]CustomerViewModel customer)
        {
            provider = new CustomerProvider();
            bool saved = provider.AddCustomer(customer);
            IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext();
            hubContext.Clients.All.getCustomers();
            return Json(new { saved = saved }, JsonRequestBehavior.AllowGet);
        }

The most important part here are these 2 lines. Basically, what this does is it gets the CustomerHub context and call the getCustomers method that we declared on the client.

IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<CustomerHub>();
hubContext.Clients.All.getCustomers();

This is the screen capture of the app running side by side updating each other. We’re done.

AppRunning

By the way, I will post a followup blog on DependencyInjection with SignalR.

Advertisements

3 thoughts on “Real Time Web with SignalR and ASP.NET MVC

Add yours

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: