A SignalR Application for Real Time Notification Using AngularJS and Toastr

3 minute read

SignalR is a new developer’s API provided for ASP.NET web applications, used to add “real time” web functionality to ASP.NET applications. “Real Time” web functionality is the ability to have server code to push contents to connected clients.

Uses of SignalR

  • Notification
  • Chat application
  • Real time monitoring application
  • Job progress update etc.

So, let’s start to create a SignalR Application. In this program I will assign a task for a person and everybody will get notification.

Step 1: Create a ASP.NET MVC application with basic template

  • Open visual studio, Got to File->New->Project
  • Select Template -> Visual C# -> Web -> ASP.NET MVC 4 Web application and click OK
  • Select Basic Template and Razor as view engine

Step 2: Install required packages

  • Install nuget package for SignalR. To install click right button of the project and then click Manages NuGet packages.
  • Search SignalR and then install “Microsoft ASP.NET SignalR” .

Run the following command in package manager console to install packages

PM> Install-Package angularjs
PM> Install-Package toastr

Step 3: Create Startup class

  • Create a Startup class in project root directory. Create Stratup.cs file and modify as follows.
using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartup(typeof(SignalRApp.Startup))]
 
namespace SignalRApp
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Step 4: Create signalR hub

  • Create a SignalR hub name NotificationHub in root directory and inherit Hub class.
  • Modify the class as follows
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace SignalRApp
{
     
    [HubName("notification")]
    public class NotificationHub : Hub
    {
         public void PushNotification(string msg)
         {
             Clients.All.response(msg);
         }
    }
}

Here Clients.All means all user will get notification. It can be configured on the basis of group and individual.

Step 5: Create HomeController and index view

Create a Home controller by right click on controller folder. Create an index view in Views->Hoome->index.cshtml by right clicking in index action of Home controller.

HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
 
namespace SignalRApp.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
 
        public ActionResult Index()
        {
            return View();
        }
 
    }
}

Index.cshtml


@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Please entry a task</h2>
<form name ="taskForm" id="taskformid" ng-controller="mainController">
    Enter a Task:
   <input name="txtTask" id="txtTask" type="text" />
   <button ng-click="sendMessage()">Send</button>
</form>

Here mainController and sendMessage() is declared. I will define it later.

Step 6: Change bundle config

  • Change BundleConfig and add customScripts, angular, signalr, jquery, toastr buddle as follows.
public class BundleConfig
{
    // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/customScripts").Include(
                  "~/Scripts/Application/app.js",
                  "~/Scripts/Application/mainController.js"));
 
 
        bundles.Add(new ScriptBundle("~/bundles/angular").Include(
                   "~/Scripts/angular.js"));
 
        bundles.Add(new ScriptBundle("~/bundles/signalr").Include(
                   "~/Scripts/jquery.signalR-2.1.2.js"));
 
                     
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));
 
        bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                    "~/Scripts/jquery-ui-{version}.js"));
 
        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));
 
 
        bundles.Add(new ScriptBundle("~/bundles/toastr").Include(
                    "~/Scripts/toastr.js*"));
 
        // Use the development version of Modernizr to develop with and learn from. Then, when you're
        // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
        bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                    "~/Scripts/modernizr-*"));
 
        //bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
 
        bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
                    "~/Content/themes/base/jquery.ui.core.css",
                    "~/Content/themes/base/jquery.ui.resizable.css",
                    "~/Content/themes/base/jquery.ui.selectable.css",
                    "~/Content/themes/base/jquery.ui.accordion.css",
                    "~/Content/themes/base/jquery.ui.autocomplete.css",
                    "~/Content/themes/base/jquery.ui.button.css",
                    "~/Content/themes/base/jquery.ui.dialog.css",
                    "~/Content/themes/base/jquery.ui.slider.css",
                    "~/Content/themes/base/jquery.ui.tabs.css",
                    "~/Content/themes/base/jquery.ui.datepicker.css",
                    "~/Content/themes/base/jquery.ui.progressbar.css",
                    "~/Content/themes/base/jquery.ui.theme.css"));
 
        bundles.Add(new StyleBundle("~/Content/css").Include(
           //"~/Content/bootstrap.css",
           "~/Content/toastr.css",
           "~/Content/site.css"));
 
 
        BundleTable.EnableOptimizations = false;
    }
}

Here I add app.js and mainController.js in customScripts bundle. I will add it later. And add bundle reference and ng-app in Views->Shared->_Layout.cshtml

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body ng-app="app">
    @RenderBody()
 
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/toastr")
    @Scripts.Render("~/bundles/signalr")
    <script src="signalr/hubs"></script>
    @Scripts.Render("~/bundles/angular")
    @Scripts.Render("~/bundles/customScripts")
     
    @RenderSection("scripts", required: false)
</body>
</html>

Step 7: Add app.js and mainController.js in Scripts->Application folder

App.js

(function () {
    angular.module('app', []);
 
    $(function () {
        $.connection.hub.logging = true;
        $.connection.hub.start();
    });
 
 
    $.connection.hub.error(function (err) {
        console.log('An error occurred: ' + err);
    });
 
    angular.module('app')
       .value('notification', $.connection.notification)
       .value('toastr', toastr);
 
})();

mainController.js

angular.module('app').controller('mainController', function ($scope, notification, toastr) {
    $scope.messages = [];
 
    $scope.sendMessage = function () {
        var inputval = taskForm.elements.txtTask.value;
        taskForm.elements.txtTask.value = "";
        notification.server.pushNotification(inputval);
        $scope.newMessage = "";
    };
 
    notification.client.response = function onNewMessage(message) {
        displayMessage(message);
        $scope.$apply();
    };
 
    function displayMessage(message) {
        toastr.success(message); //To nofiy as fadin and fadout
    }
 
});

Now run the application and write a text in text box, open two or three browser, you will get same notification like below.

Thanks for your patient !

Source code