Saturday, August 16, 2014

A smart way to fit SignalR with AngularJS

We know that SignalR is Microsoft’s solution to solve data pushing from server which has introduced in the year of 2011. Sine this year Microsoft has release couple of version of SignalR and the latest version at this time of writing article is 2.0

At the same time Angular is another framework which has bring another revolution in client side development. Now there is no way to mess all code in client even the project is large in size. Angular will help to implement MVC structure in client.

Fine, I hope you all you have more or less knowledge of both and you want to see how they fit together side by side?  

Ok, then you are in right place. We will implement SinglaR hub and then we will implement client hub factory using AngularJS and then we will consume server hub from controller. So, in nutshell, we will take help of AngularJS to create SignalR proxy and to call hub method using the proxy.
So, let’s create one MVC /normal Web Form application and give install SignalR from HuGet package manager.


Here is our simple hub code where the hub name is chatHub, you are free to give anything.

    [HubName("chatHub")]
    public class chatHub : Hub
    {
        public void broadcastHello()
        {
            Clients.All.receiveHello("Welcome to Hub");
        }
    }

Now, we will create SingnalR factory using angularJS where we will manage hub connection and proxy creation.  Have a look on below code. The module name is “myApp”, you are free to give anything.


var app = angular.module('myApp', []);

app.factory("signalrFactory", function ($rootScope, $http, $timeout) {
    var factory = {};
    factory.connection = $.connection;

    var startDoneFunctions = [];
    var debounce;

    factory.start = function (done) {
        factory.connection.hub.stop();

        if (done) {
            if (startDoneFunctions.indexOf(done) == -1) {
                startDoneFunctions.push(done);
            }
        }
        if (debounce) $timeout.cancel(debounce);
        debounce = $timeout(function () {
            factory.connection.hub.start().done(function () {
                for (var x = 0; x < startDoneFunctions.length; x++) {
                    startDoneFunctions[x]();
                }
            });
        }, 100);
    };

    return factory;
});

Now we will create our controller which will talk with the signalRFactory. Here is the code of controller.

app.controller('dataService', function ($scope, signalrFactory) {

    $scope.customerHub = signalrFactory.connection.chatHub;

    //client function to listen hub
    $scope.customerHub.client.receiveHello = function (customer) {
        $scope.returnData=  customer;
    };

    $scope.getMessage = function () {
        signalrFactory.start(function () {
            $scope.customerHub.server.broadcastHello();

        });
    };
});


The controller is pretty easy to understand, in first line we are creating hub proxy on fly by communicating with signalrFactory. Have a look that, we have injected signalrFactory to controller. receiveHello() is the client function which will listen to hub and getMessage() is the function which will call to broadcastHello() function which is defined in hub class.

Now, we will create html client from where we will consume controller of AngularJS . Have a look on below code.

@{
    Layout = null;
}
<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Data</title>
    <script src="~/Scripts/angular.min.js"></script>
    <script src="~/Scripts/jquery-1.6.4.min.js"></script>
    <script src="~/Scripts/jquery.signalR-2.1.1.min.js"></script>
    <script src="~/signalr/hubs"></script>
    <script src="~/Scripts/SignalRHub.js"></script>

</head>
<body>
    <div>
    <body ng-controller="dataService">
       
        <div ng-data="returnData"></div>
        <input type="button" name="gatdata" value="Get Data" ng-click="getMessage()" />
    </body>
    </div>
</body>
</html>

And when we will press the button, we should see the below screen.




No comments:

Post a Comment