SignalR Tutorial, Part 1: A Simple Chat Application using SignalR and AngularJS

28. August 2015 SignalR 21

Download the source project

Overview

ASP.NET SignalR provides an easy way to add real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.

SignalR provides a simple API for creating server-to-client remote procedure calls (RPC) that call JavaScript functions in client browsers (and other client platforms) from server-side .NET code. SignalR also includes API for connection management (for instance, connect and disconnect events), and grouping connections.

SignalR is a suitable technology to create chat applications or real-time dashboards which needs duplex communication between clients and the server.

The client can be of any applications such as web or windows applications, mobile application, or etc.

To get more detail explanation on what SignalR is see this: http://www.asp.net/signalr/overview/getting-started/introduction-to-signalr

Development environment

Visual Studio 2015 and .NET 4.6 is used in this tutorial. The same steps are applicable if you are using Visual Studio 2013 and .NET 4.5.

We use AngularJS which is a framework to create dynamic web applications.

You need to have IIS 8 installed as well as WebSocket protocol to be enabled on your machine.

Setting up the project

  1. In Visual Studio create a new empty ASP.NET MVC web application with no identification. Name the application SampleChat.

  1. Install SignalR via NuGet package manager. You can use the Package Manager Console, or the right click on the project and select Manage NuGet Packages.

    Search for SignalR and install the package.

Alternatively you can install the package using the following comand in NuGet Package Manager Console:

Install-Package Microsoft.AspNet.SignalR

Notice that after installation it adds jquery.signalR and jquery javascript libraries to the Script folder. SignalR is using jQuery in order to communicate with the client.

  1. Create and configure Owin Startup. Notice that after installing SignalR a readme file is opened which is guiding you configure Owin startup. To do so add an Owin Startup Class to project and name it Startup.cs.

Modify its content as below:

namespace SampleChat
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}
  1. Install AngularJs core via NuGet package manager. You can use the Package Manager Console, or the right click on the project and select Manage NuGet Packages.

    Search for AngularJs core and install the package.

Alternatively you can install the package using the following comand in NuGet Package Manager Console:

Install-Package AngularJS.Core

  1. Add a JavaScript file in Scripts folder for our chat application and name it sampleChat.js.

Create the SignalR Hub

SignalR hubs are created on the server where they listen to any incoming request and can invoke methods on any number of clients which are connected to them. The server creates long running duplex connection to the clients which connects to it via WebSocket, Server Send Event, Forever Frame, or Long Polling respectively based on the server and client infrastructure.

  1. Add a SignalR Hub Class to the project and name it ChatHub.

Note that out ChatHub class derived from the Hub base class which provides methods that communicate with SignalR connections that connected to a Microsoft.AspNet.SignalR.Hub.

It is a good practice to create a folder called Hubs and place all Hubs classes inside that. Since our project is a simple application I created that in our project root.

  1. The Hub Class already includes a method called Hello(). Clients can call this method via SignalR jQuery library and pass any data they want. This method on the sever then is getting All the Clients and invoking their JavaScript method called hello(). This method is not of our interest. Modify it as below so it can get two string values as parameter. Name and the message which user sends on the client.
public class ChatHub : Hub
{
    public void SendMessage(string name, string message)
    {
        Clients.All.broadcastMessage(name, message);
    }
}

Clients called this method and send a name and message as string. Then the Hub will broadcast that name and message to all client applications which are connected to it. So all clients will be instantly updated with the new message.

Create Client Application

Now that we have setup our Hub server we can create our client application. You can either use an MVC razor view or a simple HTML page. For simplicity we use a simple HTML file.

  1. Add an HTML file to the project and name it index.html.
  2. Add script reference to jquery, angular, and jquery.signalr JavaScript files as well as our own sampleChat.js file. You can do it by drag and drop the JavaScript files from Solution Explorer to the end of HTML body section. Take note that the order is important.
<!DOCTYPE html>
<html>
<head>
    <title></title>
	<meta charset="utf-8" />
</head>
<body>
    <script src="Scripts/jquery-1.6.4.js"></script>
    <script src="Scripts/jquery.signalR-2.2.0.js"></script>
    <script src="signalr/hubs"></script>
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/sampleChat.js"></script>
</body>
</html>

Notice the third script reference <script src=”signalr/hubs“></script> does not exist physically. This is a JavaScript proxy created by the SignalR to enables the clients to connect the server hub. You can paste the URL on the browser and see the content of the file.

Notice that at the bottom the server proxy contains the sendMessage method accepting two parameters which is map to our Hub’s SendMessage method.

You can also create this proxy manually which is useful when you want to connect to this hub from an Android phone for instance.

  1. Open sampleChat.js and modify it as below:
(function () {
    var app = angular.module('chat-app', []);
 
    app.controller('ChatController', function ($scope) {
        // scope variables
        $scope.name = 'Guest'; // holds the user's name
        $scope.message = ''; // holds the new message
        $scope.messages = []; // collection of messages coming from server
        $scope.chatHub = null; // holds the reference to hub
 
        $scope.chatHub = $.connection.chatHub; // initializes hub
        $.connection.hub.start(); // starts hub
 
        // register a client method on hub to be invoked by the server
        $scope.chatHub.client.broadcastMessage = function (name, message) {
            var newMessage = name + ' says: ' + message;
 
            // push the newly coming message to the collection of messages
            $scope.messages.push(newMessage);
            $scope.$apply();
        };
 
        $scope.newMessage = function () {
            // sends a new message to the server
            $scope.chatHub.server.sendMessage($scope.name, $scope.message);
 
            $scope.message = '';
        };
    });
}());
  1. Modify the index.html as below:

    The first textbox binds to name scope variable and the second textbox binds to message scope variable.

    The button calls our controller newMessage() method which is responsible to send the new message to the hub.

    With the ng-repeat we loop though the messages collection and displays on the view.

<body ng-app="chat-app">
 
    <div ng-controller="ChatController" >
        <div>
            Name: <input type="text" ng-model="name" /><br />
            Message: <input type="text" ng-model="message" /><br />
            <input type="button" value="Send" ng-click="newMessage()" />
        </div>
        <div>
            <ul>
                <li ng-repeat="chat in messages">
                    <span ng-bind="chat"></span>
                </li>
            </ul>
        </div>
    </div>
 
    <script src="Scripts/jquery-1.6.4.js"></script>
    <script src="Scripts/jquery.signalR-2.2.0.js"></script>
    <script src="signalr/hubs"></script>
    <script src="Scripts/angular.js"></script>
    <script src="Scripts/sampleChat.js"></script>
</body>
  1. Browse index.html on two different browsers and send messages.


21 thoughts on “SignalR Tutorial, Part 1: A Simple Chat Application using SignalR and AngularJS”

  • 1
    susanta on November 20, 2015 Reply

    how to do this exact application using in webapplication or webform

  • 3
    elimar on April 28, 2016 Reply

    interesting! mvvm right?
    nice work bro!

  • 4
    Khaled Sharafuddin on May 25, 2016 Reply

    all of this is easy stuff. The real challenge is making a swift client call remotely a signalr. It is too hard; therefore, everyone avoids it and just give simple js client running on the same server

  • 5
    metrophobe on June 4, 2016 Reply

    Great tutorial ….Question for the OP:

    How do you determine when it is more appropriate to use SignalR and when it is more appropriate to use AngularJS? Or when to combine both ?

    • 6
      Behnam on June 5, 2016 Reply

      These are totally two different technologies. SignalR enables server to client communications, AngularJS is a client side framework makes it easier to develop dynamic webpages. The main subject of this tutorial is the SignalR and how it enables server to client message broadcasting. The AngularJS here is just a client side framework I used to present data on the client. Here AngularJS can be replaced with any other Javascript frameworks, or even pure Javascript or JQuery.

      • 7
        Metrophobe on June 5, 2016 Reply

        I was not sure if Angular with it’s 2 way databinding could actually replicate this, however I guess there is no way of knowing if the data on the server changes unless a push occurs. So I guess the only equivalent technology that could currently accomplish this is by using Meteor correct?

  • 8
    Erwin on July 23, 2016 Reply

    Great post and good to get into SignalR, but it has some typos:
    End of the SampleChat.js file should be:
    ” };
    });
    }());”
    Here, the first 2 semicolons are missing.

    You say “Install-Package Microsft.AspNet.SignalR”
    Of course this has to be Microsoft instead of Microsft πŸ˜‰

    • 9
      Behnam on July 26, 2016 Reply

      Thanks Erwin noticing the typos πŸ™‚ I have fixed accordingly.

  • 10
    jj on November 25, 2016 Reply

    I was trying to follow your tutorial and couldn’t display a message after i pressed a send button.

    • 11
      Behnam on November 28, 2016 Reply

      Please download the source code and compare if you missed anything. If couldn’t solve, send me your source so I check for you. If you follow the exact steps it should be working.

      • 12
        Reinhard Panuturi Siringoringo on August 22, 2017 Reply

        Not sure if there is something wrong with the package,
        But I actually encounter this problem
        And it’s not until I install the exact package on the source code downloaded (AngularJS 1.4.4 and SignalR 2.2.0 instead of the default 1.6.5(?) and 2.2.2) that the project is actually working

  • 13
    sn on December 23, 2016 Reply

    Thanks for such a great post. I have a requirement where in i want to access SignalR service from HTML pages that are not part of the project and on other server. I tried replacing jQuery reference with CDN link and providing server url to hub connection but it did not work.

    //server where signalR is running
    $.connection.hub.url = ‘http://localhost:25466/’;
    var chat = $.connection.chatHub;

  • 14
    Sakthi Vel.S on March 18, 2017 Reply

    Great Post

    can u guide me to online users and group chat and post image and video

    • 15
      Behnam on March 19, 2017 Reply

      Thanks for you comment and interest. This post is only explaining the basics of SignalR technology. With a little twist you will be able to append users and group management and post whatever media you want. At the moment I don’t have any plan to write any post about it.

  • 16
    Amjad khan on May 19, 2017 Reply

    Awesome post…

  • 17
    Natarajan on January 12, 2018 Reply

    I am getting below error.

    SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.

    Please help.

  • 18
    Barath on July 18, 2018 Reply

    $.connection.chathub doesnot get initialized with current versions of jquery and jquery signalR libraries.
    I had to change it to older versions.

  • 19
    Abid on January 16, 2019 Reply

    hubs:1 Failed to load resource: the server responded with a status of 500 (Internal Server Error)
    angular.js:12416 Error: SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. .

  • 20
    MB on April 19, 2019 Reply

    I am trying this code and it doesn’t run. Also when I navigate to http://localhost:12907/signalr/hubs url, i get error

    Could not find a part of the path ‘~\SampleChat\SampleChat\SampleChat\bin\roslyn\csc.exe’.
    Can some one help me please?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.