Understanding SignalR From Scratch

SignalR

SignalR is a new developer's API provided for ASP.NET Web Applications by Microsoft. It is used to add "real-time" Web functionality to ASP.NET Applications. "Real Time" Web functionality is the ability of a Server code to push the contents to the connected clients. In this article, we will focus on the following things in detail-

  1. Introduction to SignalR
  2. Traditional Pooling vs. Pushing
  3. SignalR clients
  4. Working with Query client
  5. Working with .NET client.
  6. Self-hosting of SignalR Application.
  7. Understanding SignalR Methods

Before we start digging into SignalR, let's check the Wiki of SignalR.

 

SignalR is a library for ASP.NET developers used to develop real-time Web Applications (which makes use of Push Technology). If we compare the traditional Web Application with the current SignalR Application, we will understand why we should prefer SignalR.

Let's see how traditional Pulling Web Applications work.

Scenario1

Previously, when we were creating an Application like a chat app or something different, the first thing we would think is how to get the latest chats from the user, so we usually put a timer inside our page in the ASP.NET client, which calls the Web Service method or the Data access logic in every 5 seconds (depends on a timer) and updates the chat data on the client side.

This Application works perfectly for us, but it has too many problems.

  1. Increase network traffic (In each particular time the  communication happens, there is a request to the Server and gets back a response from the Server.)
  2. HTTP connections for the client-Server communication connection are re-established for each request.
  3. Delay in receiving the data due to pooling time period.

    In real-time, lots of requests from the client are wasted when there is no updated data in the Server, and it returns null in the response. If you are not maintaining your client app correctly, your whole app also refreshes in each round trip.

    When you need a continuous update from the Server, you will call the Server at a particular period of time, so in every request, a connection is established with the Server and checks for the update. If there is any update, it will talk to the client, so this is called Pulling.

Real-Time Pushing

SignalR support "server Push" is a functionality in which the Server code can call out client code in the Browser, using RPC. Server push means if any update occurs in the database, it just pushes the data to the client instead of creating a connection checking for the update, etc.

In SignalR, we have a persistent connection, which is established once in the beginning and remains.

 

Persistent Connection

As per Wiki, "HTTP persistent connection, also called HTTP keep-alive, or HTTP connection reuse, is the idea of using a single TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair. The newer HTTP/2 protocol uses the same idea and takes it further to allow multiple concurrent requests/responses to be multiplexed over a single connection."

To develop SignalR Application, we need 2 things in our Application. 

  1. HUB Class(Server side)
  2. SignalR Clients(Client side)

SignalR supports almost clients for all technologies. If we look at this, it has a client for Web, Android, iPhone, etc.

 

Before working on signalR, let's check some points.

Any class that is Inherited from the HUB class is a SignalR Hub. Hub is a Server side material and needs to be hosted.

For .NET,  we have 2 clients (a jQuery client and an ASP.NET client).

So from here, we will check how we can work with signalR.

  1. Open vs. and Create a new Web Project in Console Application.

    Now, go to the Tool and install SignalR from NuGet Package.

    Now, you will find the References given below in the project.

    You will find a Hub class also in the project.
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Threading.Tasks;  
    using Microsoft.AspNet.SignalR;  
    using Microsoft.AspNet.SignalR.Hubs;  
      
    namespace SignalRHost  
    {  
        [HubName("MyHub")]  
        public class MyHub:Hub  
        {  
      
             
        }  
    }  

    If we go to the definition of Hub, we will find the things given below inside the Hub.

    Now, we will see how we can call the SignalR Hub methods from the .NET client. I have created a method, and I want to consume this method in my .NET client.
     

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Threading.Tasks;  
    using Microsoft.AspNet.SignalR;  
    using Microsoft.AspNet.SignalR.Hubs;  
      
    namespace SignalRHost  
    {  
        [HubName("MyHub")]  
        public class MyHub:Hub  
        {  
      
            public string getdetails( string s)  
            {  
                return "Hi" + s;  
                 
            }  
             
        }  
    } 

    Now, we need to host the signalR Hub. Hence, we need OWIN to host this.

    It will add a startup.cs class, or you can add a startup class and configure the SignalR hub, as shown below.

    Now, open the startup class and write the line given below.   

Mapping the Hubs connection

To enable SignalR in your Application, create a class called Startup with the code given below. 

using System;  
using System.Threading.Tasks;  
using Microsoft.Owin;  
using Owin;  
  
[assembly: OwinStartup(typeof(SignalRHost.Startup))]  
  
namespace SignalRHost  
{  
    public class Startup  
    {  
        public void Configuration(IAppBuilder app)  
        {  
              
            app.MapSignalR();  
  
            // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888  
        }  
    }  
}  

Now, open the main method of the console Application and write the code given below to host the Hub.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
using Microsoft.AspNet.SignalR;  
using Microsoft.AspNet.SignalR.Hubs;  
using Microsoft.AspNet.SignalR.Client;  
using Microsoft.Owin.Hosting;  
  
namespace SignalRHost  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
  
            string url = "http://localhost:8077";  
            using (WebApp.Start(url))  
            {  
                Console.WriteLine("Server running on {0}", url);  
                Console.ReadLine();  
            }  
  
            System.Console.Read();  
        }  
    }  
}  

Here, we are hosting the hub on the "http://localhost:8077" URL.

Now, run the console Application, as shown below.

Run

In this way, we can host our Application using self Hosting. Now, SignalR Service is available at "http://localhost:8077".

Now, let's create another Web client Application and try to consume the Hub Method. Create another application and add signalR .NET client, as shown below.

Now, there are simple 5 steps to consume the method hosted in the Hub.

  1. Establish a connection with the URL where the Hub is hosted.
  2. Create a proxy of the Hub.
  3. Open the connection.
  4. Using the proxy object, call the method which you want to invoke.
  5. Save the result and display it in the client Application.
using Microsoft.AspNet.SignalR.Client;  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.UI;  
using System.Web.UI.WebControls;  
  
namespace SignalRChat  
{  
    public partial class chat : System.Web.UI.Page  
    {  
     public  HubConnection hubConnection = null;  
      public  IHubProxy HubProxy=null;  
        protected void Page_Load(object sender, EventArgs e)  
        {  
  
        }  
  
        protected void Button_Click(object sender, EventArgs e)  
        {  
            hubConnection = new HubConnection("http://localhost:8077/");  
             
            HubProxy = hubConnection.CreateHubProxy("MyHub");  
            hubConnection.Start();  
           Execute();  
  
            var p = HubProxy.Invoke<string>("getdetails", "Debendra").Result;  
            ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('" + p + "');", true);  
  
        }  
  
        private void Execute()  
        {  
             
            hubConnection.Start().ContinueWith(task =>  
            {  
                if (task.IsFaulted)  
                {  
                    Console.WriteLine("There was an error opening the connection:{0}",  
                                      task.Exception.GetBaseException());  
  
                    return;  
                }  
                else  
                {  
                    Console.WriteLine("Connected to Server.The ConnectionID is:" + hubConnection.ConnectionId);  
                   
                }  
  
            }).Wait();  
        }  
    }  
}  
  public class ChatHub : Hub  
    {  
        #region Data Members  
  
        static List<UserDetail> ConnectedUsers = new List<UserDetail>();  
        static List<MessageDetail> CurrentMessage = new List<MessageDetail>();  
        SqlConnection con;  
        DataSet ds;  
        DataTable dt;  
        SignalREntities _signalRDB;  
  
        #endregion  
  
        #region Methods  
  
        public void Connect(string userName, string email,string pass)  
        {  
            _signalRDB = new SignalREntities();  
            Registration reg = new Registration();  
           var id= Context.ConnectionId;  
            reg.ConnectionId= Context.ConnectionId;  
            reg.NickName= userName;  
            reg.EmailId = email;  
            reg.password = pass;  
            _signalRDB.Registrations.Add(reg);  
            _signalRDB.SaveChanges();  
  
}  
<script src="/Scripts/jquery-1.8.2.min.js"></script>
<!--Reference the SignalR library. -->  
<script src="/Scripts/jquery.signalR-1.0.0.js"></script>  
  
<!--Reference the autogenerated SignalR hub script. -->  
<script src="/signalr/hubs"></script>  
<script type="text/javascript">  
         
       $(function () {  
  
           // Declare a proxy to reference the hub.   
           var chatHub = $.connection.chatHub;  
  
           registerClientMethods(chatHub);  
  
           // Start Hub  
           $.connection.hub.start().done(function () {  
  
               registerEvents(chatHub)  
  
           });  
  
       });  
            function registerEvents(chatHub) {  
  
           $("#btn_register").click(function () {  
  
               var name = $("#txt_NickName").val();  
               var email = $("#txt_email").val();  
               var password = $("#txt_password").val();  
                 
               if (name.length > 0) {  
                   chatHub.server.connect(name,email,password);  //It will call the connect method on Hub
               }  
               else {  
                   alert("Please enter name");  
               }  
  
           });  
  
   </script>  
<body class="blue">  
  
  
  <div id="login-page" class="row">  
    <div class="col s12 z-depth-6 card-panel">  
      <form class="login-form" runat="server">  
        <div class="row">  
          <div class="input-field col s12 center">  
          
              <img src="Images/240_F_98129226_SNcpf7qMgTgJikjE4xdskEHEgV465gnN.jpg" width="120" />  
          </div>  
        </div>  
        <div class="row margin">  
          <div class="input-field col s12">  
            <i class="mdi-social-person-outline prefix"></i>  
          
              <asp:TextBox ID="txt_NickName" runat="server"></asp:TextBox>  
             
          </div>  
        </div>  
        <div class="row margin">  
          <div class="input-field col s12">  
            <i class="mdi-communication-email prefix"></i>  
           
               <asp:TextBox ID="txt_email" runat="server"></asp:TextBox>  
             
          </div>  
        </div>  
        <div class="row margin">  
          <div class="input-field col s12">  
            <i class="mdi-action-lock-outline prefix"></i>  
            <input id="txt_password" type="password" class="validate">  
              
          </div>  
        </div>  
        
          
        <div class="row">  
          <div class="input-field col s12">  
            
              <asp:Button ID="btn_register" Text="Register" runat="server" />  
          </div>  
          <div class="input-field col s12">  
            <p class="margin center medium-small sign-up">Already have an account? <a href="login.aspx">Login</a></p>  
          </div>  
        </div>  
      </form>  
    </div>  
  </div>    
    
</body>  

The result is given below.

Res

Now, let's check how to call a Hub method using a JavaScript client. Let's have the method given below in the HUB.

I have simply created a Create method in my Chat Hub. Now, I want to call this method from a Javascript client. First, add JavaScript references given below on the page.

Now, my JavaScript client code is given below.

Hence, my UI is given for the code given below.

image

Now, let's enter the details and click on register the button.

image

As per the logic, it will execute the Hub Connect method.

Conclusion

In this way, in JavaScript, we can call the Server Hub method. I hope you understand the basics of SignalR. If you have any doubts about this, please let me know so I can try to explain it more clearly.

In my next article, we will work on a SignalR project.


Similar Articles