Introduction To SignalR With ASP.NET Core

Introduction
 
SignalR is an open source library that adds real-time web functionality to applications. It means, it enables the server-side to push the content to the client instantly rather than the server having to wait for clients to request new data. It provides an API for creating server to client RPC (remote procedure calls). The RPC call JavaScript functions on the client from the server side in .net core code.
 
SignalR can be used for,
  • Applications that require high frequency updates from the server such as social networking, voting ect.
  • Applications that require notifications such as email, games, etc.
  • Dashboards and monitoring applications
SignalR has been rewritten for ASP.net core 2.1. It includes following improvements,
  • No JQuery dependency
  • Support custom protocols
  • A new compact binary protocol based on MessagePack
  • Streaming response model
  • Simplified scale-out model
  • WebSockets support
Following are some features of SignalR,
  • It handles connection management automatically
  • Able to send the message to all connected client simultaneously
  • Able to send the message to specific client or groups of client
  • Scales in/out automatically to handle traffic
SignalR supports many techniques for handling real-time communications such as Web Sockets, Server-Sent Events, and Long Polling. It automatically selecs the best transport method which is suitable for both server and client.
 
Hubs
 
The Hubs are used to communicate between server and client in SignalR. It is a high level pipeline that allows the client and server to call methods on each other. SignalR automatically handles the dispatching across machine boundaries that allows the server to call methods on the client and vice versa.
 
SignalR provides two built-in hub protocols
  • Text protocol (based on JSON)
  • Binary Protocol (based on MessagePack)
MessagePack creates smaller messages than JSON. Older browsers must support XHR level2 to provide support to MessagePack.
Hubs call client side method by sending the messages which contain the name of the method and its parameter. This method parameter is deserialized using the configured protocol. If the client matches the name of method it calls the method and pass the deserialized parameter data.
 
Get started with SignalR
 
In this example, I have create a simple Chat application.
 
The following software is installed to develop applications with SignalR on ASP.net core
First step is to to create the web application. The web application can be created by using either Visual Studio or CLI.
 
 
 
We can acheive the same thing using CLI by using the following command. 
  1. dotnet new webapp  
 Next step is to download SingleR module using node package manager.
  1. npm init -y  
  2. npm install @aspnet/signalr  
 
 
Next step is to copy signalr.js file from "node_modules\@aspnet\signalr\dist\browser" to appropriate folder of our project. In this demo I have created folder "singler" under inside the wwwroot/lib folder and paste this file.
 
Do not forget to include signalr.js file into script tag.
 
Create SignalR Hub
 
The SignalR hub is a class that inherits from Microsoft.AspNetCore.SignalR.Hub. In this class, we can create a method that can be accessed from JavaScript. To send messages to all clients, I have created "SendMessage" method and within this method, I have called the "RecieveMessage" method of the connected client.
  1. using Microsoft.AspNetCore.SignalR;  
  2. using System.Threading.Tasks;  
  3. namespace ChatApp  
  4. {  
  5.     public class ChatHub : Hub  
  6.     {  
  7.         public async Task SendMessage(string user, string message)  
  8.         {  
  9.             await Clients.All.SendAsync("ReceiveMessage", user, message);  
  10.         }  
  11.     }  
  12. }  
Next is to configure our project that handles the SignalR Request. To configure SignalR in our project, we need to add signalR service to ConfigureService method of startup class.
  1. public void ConfigureServices(IServiceCollection services)  
  2. {  
  3.     ....  
  4.     ....
  5.     services.AddMvc();  
  6.     services.AddSignalR();  
  7. }  
Also, we need to configure the route to SignalR hubs using UseSignalR method defined in the configure method of startup class. This method(app.UseSignalR) adds SignalR to a middleware pipeline. 
  1. public void Configure(IApplicationBuilder app)  
  2. {  
  3.     ...  
  4.     ...  
  5.     app.UseSignalR(routes =>  
  6.     {  
  7.            routes.MapHub<ChatHub>("/chatHub");  
  8.      });  
  9.   
  10.      app.UseMvc();  
  11. }  
Using following JavaScript code, we can call the server method "SendMessage" and also we have register ReceiveMessage method, that can be called from server to send send the message to client. This code is written for modern ECMAScript 6, so this code will not work with IE 11 or the other browser that does not support ECMAScript 6.
 
In this demo, I have created chat.js file under "wwwroot/js" folder.
  1. const connection = new signalR.HubConnectionBuilder()  
  2.     .withUrl("/chatHub")  
  3.     .build();  
  4.   
  5. //This method receive the message and Append to our list  
  6. connection.on("ReceiveMessage", (user, message) => {  
  7.     const msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");  
  8.     const encodedMsg = user + " :: " + msg;  
  9.     const li = document.createElement("li");  
  10.     li.textContent = encodedMsg;  
  11.     document.getElementById("messagesList").appendChild(li);  
  12. });  
  13.   
  14. connection.start().catch(err => console.error(err.toString()));  
  15.   
  16. //Send the message  
  17.   
  18. document.getElementById("sendMessage").addEventListener("click"event => {  
  19.     const user = document.getElementById("userName").value;  
  20.     const message = document.getElementById("userMessage").value;  
  21.     connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));  
  22.     event.preventDefault();  
  23. });   
For demo purposes, I have replaced the following content in Pages\index.cshtml file.
  1. @page  
  2. <div class="container">  
  3.     <div class="row"> </div>  
  4.     <div class="row">  
  5.         <div class="col-md-12">  
  6.             <div class="col-md-6">  
  7.                 <div class="col-md-3">User</div>  
  8.                 <div class="col-md-9"><input type="text" id="userName" /></div>  
  9.             </div>  
  10.         </div>  
  11.         <div class="col-md-12">  
  12.             <div class="col-md-6">  
  13.                 <div class="col-md-3">Message</div>  
  14.                 <div class="col-md-9">  
  15.                     <input type="text" id="userMessage" />      
  16.                     <input type="button" id="sendMessage" value="Send Message" />  
  17.                 </div>  
  18.             </div>  
  19.         </div>  
  20.     </div>  
  21.     <div class="row">  
  22.         <div class="col-12">  
  23.             <hr />  
  24.         </div>  
  25.     </div>  
  26.     <div class="row">  
  27.         <div class="col-6"> </div>  
  28.         <div class="col-6">  
  29.             <ul id="messagesList"></ul>  
  30.         </div>  
  31.     </div>  
  32. </div>  
  33. <script src="~/lib/signalr/signalr.js"></script>  
  34. <script src="~/js/chat.js"></script>  
Output
 
 
 
You can view or download the source code from the GitHub link here