In this article, we will learn about what are real-time web applications & how to build real-time web applications using SignalR in ASP.NET Core C#. As part of this article for demonstration of SignalR implementation in ASP.NET Core, we will build an application that can send real-time public messages/alerts to all connected users or private messages targeted to some specific user(s).
I will upload the entire source code for the real-time web application, developed as part of this article, to GitHub & provide the link for the same at the end of this article.
Table of Contents
Introduction to Real-time Web Applications
The real-time web is defined as the technology that enables users to receive up to date information, without making any request for data update refresh action or update button click, as soon as it is published by the data publisher.
In traditional applications i.e. applications that are not real-time users don’t have any idea of changing data on the server and only come to know about the modified data only after the user tries to inquire about the data from the server. Whereas in real-time applications client applications opens a 2-way channel with the server using which the client or server can send messages to each other without any request from the client. As soon as there is a change in data on the server then that is sent to the client on a real-time basis. The server can send public messages to all the connected clients or it is even capable to send private messages directed to specific users.
Real-time web applications allow users to receive the latest information, like messages, alerts, or application/user-specific data, as soon as data changes (add/modify/delete) on the server without the need for the user to request the data.
There are many examples of real-time applications one of them is Gmail which displays new emails without the need for users to refresh or reload. Web application from stock exchanges is one of the greatest examples of real-time web applications where stock prices are communicated to connected browsers without the need for clients to request the data. SignalR in ASP.NET Core is used to build real-time web applications.
Also, there is a need for real-time data transmitting from IoT devices. Alerts from IoT devices like any change in monitored parameters should be processed and forwarded to users without any delay. Also, vise-versa i.e. commands from users should reach IoT devices without any delays.
The major social platform platforms like Facebook & Twitter which are one of the main ways of communication are built upon real web technologies.
In the case of real-time applications, the server should be smart enough to detect changes and send changes to connected clients i.e. browsers, applications, mobile apps, etc.
Introduction to SignalR
SignalR is a library that can be used to develop real-time web applications in ASP.NET Core. SignalR contains an API that allows server-side code to send messages to connected client browsers.
SignalR enables web application servers to push messages to the clients who are connected to the servers as soon as the data is available on the server for the push. As this data is available on a real-time basis at the client-side it makes this SignalR technology very important to build modern web applications that are expected to deliver the latest data without the need to hit the refresh button i.e. provide the latest data directly from the server as soon as it is available on the server like in chat applications, games, stock price application, monitoring applications, etc.
SignalR in ASP.NET Core uses Remote Procedure Call to enable the server to call a function on the client using underlying transport. SignalR in ASP.NET core allows running on many platforms, other than windows, which are supported by ASP.NET Core. SignalR client SDKs are available for Javascript, .NET (C#, F# and Visual Basic) and Java which makes it possible to connect to SignalR Hub to receive messages almost from any platform including web apps, mobile, etc.
SignalR based applications can be hosted by anyone on their servers and if need be then SignalR is also available on the Azure Cloud Platform as a service for a fully managed platform.
The speed to deliver the latest data to the client and great user experience is an important factor in today’s modern web applications development and keeping that in mind SignalR was built for high performance and is one of the fastest real-time frameworks around.
The most important SignalR in ASP.NET Core C# is not open-source on GitHub just like the rest of the .NET
SignalR Transports
SignalR uses transports for sending messages from server to client. Following Transports are supported by SignalRin ASP.NET Core C#
- Long Polling
- Server-Sent Events
- WebSockets
SignalR has provided a wrapper around these low-level transports which allow developers to just focus on business requirements instead of worrying about underlying transport being used for sending and receiving messages between client and server. Based on the browser and the version of the browser being used by the real-time web application SignalR in ASP.NET Core C# automatically decides about the underlying transport to be used. The fallback mechanism is used to decide upon the transport layer that will be used by the application.
WebSockets is the most efficient transport option but this requires the latest browser supporting web sockets and if the client is running an old browser then instead of web sockets SignalR in ASP.NET Core C# will fall back on Server-Sent events & if Server-Sent events are also not supported in the browser being used then SignalR will fall back on long polling mechanism for the transport layer.
SignalR Hub
SignalR uses hubs to communicate between clients & servers. Hub is a component that is hosted in your ASP.NET Core Application. Hub sends messages to & receives messages from the client using a remote procedure call using underlying transport. Essentially SignalR Hub is a central point in the ASP.NET Core and this hub is responsible for routing all the communication messages in the ASP.NET Core C# application
A combination of hub & remote procedure calls enables real-time web applications using SignalR in ASP.NET Core. Hub in ASP.NET Core application is a class derived from the hub base class.
SignalR hubs in ASP.NET Core now supports dependency injection via a constructor in the same way as the controller in ASP.NET Core.
Implement SignalR in ASP.NET Core C#
This will get you started with the implementation of SignalR in ASP.NET Core MVC Web Application.
For demonstration application development purposes, we will make use of Visual Studio Community 2022 Version 17.1.2 with .NET 6.0 SDK
Overall Approach for Demonstration of SignalR in ASP.NET Core
- We will first create an application of the type ASP.NET Core Web App MVC and name it as ProCodeGuide.Samples.SignalR6
- We will add the required client-side package for SignalR to the application
- We will add and configure the code for SignalR in ASP.NET Core C# i.e. Create Hub and configure SignalR & hub in the Program.cs file
- We will add the required Javascript for Client code for SignalR configuration in the client i.e. add code to connect to message hub and register handler to receive messages
- We will add the UI to enable users to send messages to other users i.e. add a menu item along with the controller & its View. Also, add javascript to invoke Send Message of the Hub
- Finally, we will run & test the code
Here is a quick & short video on the demonstration of how to implement SignalR in ASP.NET Core
Create ASP.NET Core MVC project
For demonstration purposes, we will be creating a new project of the type ASP.NET Core Web App MVC as per the screenshots shown below with the name as ProCodeGuide.Samples.SignalR6
Install required packages for SignalR
The server-side library for SignalR is included in ASP.NET Core 6 framework so there is not need to install any server-side NuGet package but the client-side JavaScript library for SignalR in ASP.NET Core C# needs to be added to the project. Follow below to add the SignalR JavaScript library to the project
- In Solution Explorer right-click on project & select Add->Client-Side Library..
- On the Add Client-Side Library screen shown below select provider ‘unpkg‘ & enter ‘@microsoft/signalr@latest‘ for library
- Choose specific files to be added i.e. File/dist/browser/signalr.js & File/dist/browser/signalr.min.js as per screenshot shown below)
- set target location & click on install
The above steps will add SignalR JavaScript Library to the project under folder wwwroot/lib/microsoft/signalr/dist/browser as shown below
Add & Configure the Server
Create a SignalR Hub
Hub is a class that handles client-server communication in SignalR in ASP.NET Core C#. The client connects to the hub to receive messages. Create a hub class named MessageHub that derives from the base class Hub as shown in the below code.
public class MessageHub : Hub { public async Task SendMessage(string user, string message) { if (string.IsNullOrEmpty(user)) await Clients.All.SendAsync("ReceiveMessageHandler", message); else await Clients.User(user).SendAsync("ReceiveMessageHandler", message); } }
Hub SendMessage method takes 2 parameters i.e. user to which message is to be sent and the message itself which is to be sent. Now if a user is blank then the message will be sent to all connected users and if a user is specified then the message will be sent only to that specified user.
Hub calls SendAsync method that takes 2 parameters, first one is the method name ‘ReceiveMessageHandler’ which is called on the client using a remote procedure call so each client connecting to this hub has to implement this method to receive messages from the hub & other is the message itself which will be passed to client method ‘ReceiveMessageHandler’ while calling that method.
Configure SignalR in ASP.NET Core Application
Configure SignalR in the ASP.NET Core application by adding the below code in the program.cs file
var builder = WebApplication.CreateBuilder(args); // Add services to the container. var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services.AddControllersWithViews(); builder.Services.AddSignalR(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.MapRazorPages(); app.UseEndpoints(endpoints => { endpoints.MapHub<MessageHub>("/messagehub"); }); app.Run();
Here SignalR service is configured at the startup of the application & an endpoint is added for MessageHub which will be used by the client to connect to the SignalR Hub.
Add the Client Code
Now let’s add the client code to connect to the hub & add the JavaScript method named receiveMessageHandler which will be called by MessageHub while sending messages to the client.
Add JavaScript code to connect to Hub & Method to Receive Message
We will add a JavaScript file named ConnectSignalR.js on the path wwwroot/js/ that will connect the client to MessageHub & also implements the client function ‘ReceiveMessageHandler’ to receive messages from the hub. Below code is added to the wwwroot/js/ConnectSignalR.js file.
"use strict"; var connection = new signalR.HubConnectionBuilder().withUrl("/messagehub").build(); connection.start(); connection.on("ReceiveMessageHandler", function (message) { var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); alert(msg); });
Now let’s load this JavaScript file in the ASP.NET Core application. We will load this JavaScript in _Layout.cshtml file after successful login i.e. for authenticated users only as shown below code.
@if (SignInManager.IsSignedIn(User)) { <script src="~/lib/microsoft/signalr/dist/browser/signalr.js"></script> <script src="~/js/ConnectSignalR.js"></script> }For
The above code will load a client library file for SignalR and also as per code in ConnectSignalR.js will connect the client to MessageHub for authenticated users.
To use SignInManager in the cshtml file we will have to import the below namespaces in the cshtml file i.e. in _Layout.cshtml file.
@using Microsoft.AspNetCore.Identity @inject SignInManager<IdentityUser> SignInManager
Now that we have added & configured the required SignalR code for the server & client side now let’s add the UI to enable connected users to send messages to all the connected users or to a specific connected user.
Let’s wire the UI
Now let’s add a user interface i.e. controller, view and menu to load this new view to allow users to send messages to all other connected users or to a specific connected user.
Add SendMessage action to the Home controller
Add the below action method for the SendMessage action in Controllers/HomeController.cs
[Authorize] public IActionResult SendMessage() { return View(); }
Next, let’s add a view for the above action method.
Add View for SendMessage action
We will create a view that will allow users to send messages to all connected users or to specific connected users. Note that we will be adding this view for all users but will be available for authenticated users only i.e. any logged-in user can access this view but if there is a need then this view can be restricted to users with specific roles i.e. only users with the specified role will be capable to send messages/alerts to other connected users.
Following view is added under Views/Home/SendMessage.cshtml
@page <div class="container"> <div class="row"> </div> <div class="row"> <div class="col-2">To User</div> <div class="col-4"><input type="text" id="userInput" /></div> </div> <div class="row"> <div class="col-2">Message</div> <div class="col-4"><input type="text" id="messageInput" /></div> </div> <div class="row"> </div> <div class="row"> <div class="col-6"> <input type="button" id="sendButton" value="Send Message" /> </div> </div> </div> <script src="~/js/SendMessage.js"></script>
Below is the code that will be added to the JavaScript file named SendMessage.js on the path wwwroot/js/ to call the method in the hub on the server using a remote procedure call. This demo application will make a remote call to the SendMessage method in the MessageHub.
"use strict"; document.getElementById("sendButton").addEventListener("click", function (event) { var user = document.getElementById("userInput").value; var message = document.getElementById("messageInput").value; connection.invoke("SendMessage", user, message).catch(function (err) { return console.error(err.toString()); }); event.preventDefault(); });
As the MessageHub method, SendMessage requires 2 parameters from the calling code so accordingly user & message has been passed to call the SendMessage function.
Finally, letās add the menu to call the SendMessage action in Home Controller that will load view SendMessage for the logged in users. Again Send Message link is added only for authenticated users as shown below.
@if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="SendMessage">Send Message</a> </li> }
The above code has been added in _Layouts.cshtml file under the list for navigation items.
Finally, run the code & verify the results
Before you run the code don’t forget to execute the below-mentioned commands in the package manager console to automate the migrations & create the database.
add-migration InitialMigration update-database
After running the code to test the messaging feature of SignalR in ASP.NET Core C# register at least 3 users in the application and log in with all 3 users from different browsers to test send message functions for all & specific users. Below are the home screens for all the 3 users after login. Since these are the screens after successful login the menu Send Message is available for all the 3 users.
Next navigate to Send Message view for any one of the 3 logged in users and send a message to all the connected users by not specifying the value for the To User field. This should send a message to all the 3 connected users including the user who has initiated the message.
We can see from the above screens that all the 3 connected users received the message. Next, we will try to send messages to a specific user. For messages to a specific user, you will have to type the Id of the user to whom the message is to be sent. Since we have used Identity for user management you will have to go to the database table AspNetUsers to find out the Id of the user to whom the message is to be sent.
We can see from the above screen that message was received by only one user whose Id was specified in the To User to send the message.
You can enhance the application to type the login id instead of the user if in the To User Field and replace the login id with the user Id on the server. You can even change the To User to dropdown to display the list of all the connected users to select the specific user to send a message.
Summary
In this article, we learned in detail about what are modern real-time applications, SignalR, SignalR Hub & how to get started with SignalR in ASP.NET Core C# application.
This was just a simple example of getting started with SignalR in ASP.NET Core 6 but you build amazing modern applications using SignalR in ASP.NET Core 6.
Please provide your suggestions & feedback in the comments section below
You can check my other trending articles ā Build Resilient Microservices (Web API) using Polly in ASP.NET Core & Microservices with ASP.NET Core 3.1 ā Ultimate Detailed Guide
Download Source Code
Here you can download the complete source code for this article demonstrating how to build real-time web applications using SignalR in ASP.NET Core C#
Below is the link to the sample source code developed using ASP.NET Core 3.1
https://github.com/procodeguide/SignalR.Sample
Below is the link to the sample source code developed using SignalR in ASP.NET Core 6
https://github.com/procodeguide/ProCodeGuide.Samples.SignalR6
FAQ
What is Real-Time Web?
Real-time web applications allow users to receive the latest information, like messages, alerts, or application/user-specific data, as soon as data changes (add/modify/delete) on the server without the need for the user to request the data.
What is SignalR?
SignalR is a library that can be used to develop real-time web applications in ASP.NET Core.
How does SignalR Works?
SignalR contains an API that allows server-side code to send messages to connected client browsers.
Which Transports are supported in SignalR in ASP.NET Core?
SignalR support transports long polling, Server-Sent Events & WebSockets in ASP.NET Core.
It’s a great tutorial, thank you for it. š
Thank you!
Amazing Article really love it, you have explained it very well
Thanks for your feedback!
I’m having an issue with this. It works for Clients.All.SendAsync, but not for Clients.User(user).SendAsync. Any ideas why this is happening?
Hi, did you try with the source code provided on Github for this article?
Iām having an issue with this. It works for Clients.All.SendAsync, but not for Clients.User(user).SendAsync. I tried your source code that’s working but I am doing the same but it does not work for specified user. do you have any idea what’s can be happening here?
For messages to a specific user, you will have to ensure that the user to whom the message is being sent is logged in and you will have to enter the user’s ID to whom the message is to be sent. Since Identity has been used for user management you will have to go to the database table AspNetUsers to find out the Id of the user to whom the message is to be sent and input the sane in the To User text box.
Very Nice detailed Article 10/10 with 5 stars *****
the command add-migration InitialMigration fails, build fails, can anyone plesae help why