top of page

What is SignalR and how can it be used to build real-time web applications in ASP.NET?

Updated: Sep 20, 2023

In today's programming world, the demand for real-time web applications has grown exponentially. Whether it's live chat, collaborative editing, online gaming, or any scenario where instant updates and communication are critical, users expect web applications to deliver information and interactions in real time.


Enter SignalR, a powerful technology within the ASP.NET ecosystem that revolutionizes the way developers create dynamic and responsive web applications.


In this article, we will delve into the world of SignalR, exploring its fundamental concepts, architecture, and the myriad ways it empowers developers to construct real-time web applications that keep users engaged and informed.


By the end, you'll have a comprehensive understanding of SignalR's capabilities and be ready to embark on your journey to building real-time web applications with confidence. Let's start by demystifying the core question: What is SignalR, and how can it transform your web development endeavors?


Table of Contents:
  1. Create a Project

  2. Add SignalR Client Library

  3. Create SignalR Hub

  4. Configure SignalR

  5. Add SignalR Client Code

  6. Run the App


What is SignalR?

SignalR is a free and open-source software library for Microsoft ASP.NET that allows server code to send asynchronous notifications to client-side web applications. This means that the server can push data to the client without the client having to poll the server for updates. This makes it ideal for real-time applications such as chat, gaming, and collaboration tools.


Here are some of the benefits of using SignalR for ASP.NET developers:

  • Real-time updates: SignalR allows you to push data to the client as soon as it becomes available, without the client having to poll the server. This makes your applications feel more responsive and engaging.

  • Easy to use: SignalR is very easy to use, even for developers with no experience with real-time web development.

  • Scalable: SignalR is scalable, so you can use it to build applications that can handle a large number of concurrent users.

  • Secure: SignalR uses industry-standard security protocols to protect your data.

If you are an ASP.NET developer and you need to build a real-time application, then SignalR is the perfect choice for you. It is easy to use, scalable, and secure.


SignalR is supported on the following platforms and browsers:

  • Windows, macOS, Linux

  • Chrome, Firefox, Edge, Safari

  • Android, iOS

SignalR can also be used on other platforms and browsers, but it may require additional configuration.


What is a Real-time web Application?

A real-time web application in ASP.NET is a web application that allows for bi-directional communication between the client and the server. This means that the server can push data to the client without the client having to poll the server for updates. This makes it possible for real-time applications such as chat, gaming, and collaboration tools to work seamlessly.


ASP.NET SignalR is a library that can be used to build real-time web applications in ASP.NET. SignalR uses a variety of techniques to establish a persistent connection between the client and the server, such as Web Sockets, Server-Sent Events, and Long Polling. This allows SignalR to provide low latency and high throughput for real-time applications.


Here are some examples of real-time web applications that can be built with ASP.NET SignalR:

  • Chat applications

  • Gaming applications

  • Collaboration tools

  • Live streaming applications

  • IoT applications

  • Financial trading applications

  • Healthcare applications


SignalR Architecture

Consider the below image that shows the architecture of SignalR. It shows how the different components of SignalR work together to provide real-time communication between clients and servers.

SignalR Architecture

The top layer is the client side application. This is the part of the application that the user sees and interacts with. It is typically written in HTML, CSS, and JavaScript.


The server-side .NET application is connected to the Data Access, Caching, Logging, and Security components. These components provide the functionality that is needed to build a robust and secure web application.


The next layer is the transport layer. This layer is responsible for sending and receiving data between the client side application and the server-side application. The most common transport layer protocols are HTTP and HTTPS.


The server side application is responsible for processing the requests from the client side application and generating the responses. It is typically written in a language like .NET, Java, or PHP.


The Hubs API and PersistentConnection API are two APIs that can be used to improve the performance of web applications.

  • The Hubs API allows multiple clients to communicate with each other without having to go through the server.

  • The PersistentConnection API allows the client and server to keep a connection open for a period of time, which can improve the performance of long-running tasks.

The Transports layer is a catch-all for any other transport protocols that may be used by the web application.


Component

Below are the main components of SignalR:


1. Hubs

The hubs are used to provide a way for clients to communicate with each other and with the server. Hubs are objects that are defined on the server. Clients can connect to hubs and call methods on the hub. The methods on the hub can be used to send messages to other clients, or to get data from the server.


2. Transports

The transports are the protocols that SignalR uses to communicate with the clients. SignalR supports several transports, including WebSockets, Server-Sent Events, and HTTP long polling. The transport is chosen by the negotiator. The negotiator takes into account the capabilities of the client and the server, as well as the network conditions.


3. Negotiator

The negotiator is responsible for selecting the best transport for the current connection. The negotiator takes into account the capabilities of the client and the server, as well as the network conditions. The negotiator will choose the transport that is most likely to succeed in establishing a connection and providing a good user experience.


4. Serializer

The serializer is responsible for serializing and deserializing objects that are sent between the client and the server. The serializer converts objects into a format that can be sent over the wire. The serializer also converts objects that are received from the wire into a format that can be used by the application.


How does SignalR Work?

Consider the below image that illustrates the communication between the client and the server in a SignalR Application. The client sends a request to the server, and the server sends a response back to the client. The communication between the client and the server is handled by the SignalR library.

How does SignalR work?

In the diagram, we have:

  • Client ID: The client ID is a unique identifier for the client. The client ID is used by the server to keep track of the different clients.

  • Hub Proxy: The hub proxy is a JavaScript object that is used by the client application to communicate with the SignalR hub.

  • Server invocation of client method myClientFunc(): This shows how the server can invoke a method on the client. The server can invoke a method on the client by calling the invoke() method on the hub proxy.

  • Client invocation of server method myServerFunc(): This shows how the client can invoke a method on the server. The client can invoke a method on the server by calling the invoke() method on the hub.

The client-side consists of the following components:

  • Client application: The client application is the code that runs on the client's browser or device. The client application is responsible for connecting to the server and sending and receiving messages.

  • SignalR client library: The SignalR client library is a JavaScript library that is used by the client application to connect to the server and send and receive messages.

The server side consists of the following components:

  • SignalR hub: A SignalR hub is a way for clients to communicate with each other and with the server. Hubs are objects that are defined on the server. Clients can connect to hubs and call methods on the hub.

  • SignalR server library: The SignalR server library is a .NET library that is used by the server to create and manage SignalR hubs.

Below we have a brief explanation of how the components of SignalR work together:

  1. The client application sends a request to the server.

  2. The SignalR server library on the server receives the request and creates a connection to the client.

  3. The SignalR server library on the server creates a SignalR hub.

  4. The client application connects to the SignalR hub.

  5. The client application can now call methods on the SignalR hub.

  6. The SignalR hub can send messages to all of the connected clients.


Steps to build Real-Time Web Applications with SignalR

Here are the steps you can follow to create a real-time web application in ASP.NET using SignalR:


STEP 1: Create a Project

Step 1: Open Visual Studio IDE.


Step 2: Select Project Template

Go to the "File" menu and select "New" => "Project..." to create a new project.


SignalR in ASP.NET - Create project in VS code

In the "Create a new project" window, select "ASP.NET Core Web App" as the project template. You can find this under the "Web" section.


SignalR in ASP.NET - create new project

Step 3: Configure the Project

Click the "Next" button to proceed to the project configuration step.


Under "Configure your new project," enter "SignalRChat" for the Project name. You can choose a different name if you prefer.


Click the "Next" button to continue.


Step 4: Additional Information

In the "Additional information" section, select ".NET 7.0 (Standard Term Support)" as the target framework. This is the version of .NET you want to use for your project.


Click the "Create" button to create your ASP.NET Core Web App project with SignalRChat as the name and .NET 7.0 as the target framework.


SignalR in ASP.NET - Additional information

You have now successfully created a new ASP.NET Core Web App project with SignalR integration using Visual Studio IDE. You can proceed to the next steps to set up SignalR and build your real-time chat application.


STEP 2: Add SignalR client Library

In this step, you are adding the SignalR client library to your project.


While the SignalR server library is included in the ASP.NET Core shared framework, you need to manually add the JavaScript client library to your project. You are using Library Manager (LibMan) to get this client library from the unpkg content delivery network.


Follow the below steps to add the SignalR client Library:


STEP 1: In Solution Explorer, right-click the project and select Add => Client-Side Library.


STEP 2: A prompt box will appear, where you need to do the following:

  1. Select unpkg for Provider

  2. Enter @microsoft/signalr@latest for Library.

  3. Select Choose specific files, expand the dist/browser folder, and select signalr.js and signalr.min.js.

  4. Set Target Location to wwwroot/js/signalr/.

  5. Select Install.

Add SignalR client library

This step ensures that you have the necessary SignalR client library files in your project, which you will use to establish a connection to the SignalR hub from the client side.


STEP 3: Create SignalR Hub

In this step, you are creating a SignalR hub class. A hub is a communication endpoint in SignalR that allows clients to interact with the server and with each other in real-time.


In your project's folder, create a "Hubs" folder.


Inside the "Hubs" folder, create a class called "ChatHub" with the provided code.

using Microsoft.AspNetCore.SignalR;

namespace SignalRChat.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

The ChatHub class inherits from the Hub class, which is provided by SignalR. It contains a method SendMessage that can be called by connected clients to send messages to all clients.


STEP 4: Configure SignalR

In this step, you are configuring the SignalR server to handle SignalR requests. You need to add the provided code to your "Program.cs" file.

using SignalRChat.Hubs;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddSignalR();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseAuthorization();

app.MapRazorPages();
app.MapHub<ChatHub>("/chatHub");

app.Run();

The above code:

  • Adds SignalR to the ASP.NET Core dependency injection and routing systems.

  • Maps the "ChatHub" to the "/chatHub" URL, which means that clients can connect to this hub using this URL.


STEP 5: Add SignalR Client Code

In this step, you are adding the client-side code that will interact with the SignalR hub.


You replace the content in your "Pages/Index.cshtml" file with the provided HTML and JavaScript code.

@page
<div class="container">
    <div class="row p-1">
        <div class="col-1">User</div>
        <div class="col-5"><input type="text" id="userInput" /></div>
    </div>
    <div class="row p-1">
        <div class="col-1">Message</div>
        <div class="col-5"><input type="text" class="w-100" id="messageInput" /></div>
    </div>
    <div class="row p-1">
        <div class="col-6 text-end">
        <input type="button" id="sendButton" value="Send Message" /></div>
    </div>
    <div class="row p-1">
        <div class="col-6">
            <hr />
        </div>
    </div>
    <div class="row p-1">
        <div class="col-6">
            <ul id="messagesList"></ul>
        </div>
    </div>
</div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

The above code creates an interface for users to input their name and messages and a button to send messages. It includes references to the SignalR client library and a "chat.js" script that contains the client-side logic.


In the wwwroot/js folder, you create a "chat.js" file with the provided JavaScript code.

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable the send button until connection is established.
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it is not interpreted as markup. If you're assigning in any other way, you should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

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();
});

The above code establishes a connection to the "ChatHub" on the server. It disables the send button until the connection is established. It defines a function to handle received messages and appends them to the message list. It starts the connection and adds an event listener to send messages when the button is clicked.


STEP 6: Run the App

To test your SignalR application:

  1. Press Ctrl + F5 to run the app without debugging.

  2. Copy the URL from the address bar, open another tab, and paste the URL.

  3. Choose a browser, enter a name and message, and select the "Send Message" button.

Your application should now allow real-time messaging between clients using SignalR. Messages sent by one user will be displayed instantly to all connected users.


SignalR Communication Modes

In SignalR, a persistent connection is used to maintain a connection between the client and the server even when there is no data being sent. This allows SignalR to provide real-time communication between clients and the server, even when the client is not actively sending or receiving data.


SignalR uses a variety of techniques to maintain persistent connections:

  1. WebSockets,

  2. Server-Sent Events

  3. Long Polling.

The technique that is used depends on the capabilities of the client and the server, as well as the network conditions.


1. WebSockets: WebSockets is a full-duplex protocol that allows for two-way communication between the client and the server. WebSockets is the preferred communication mode for SignalR because it provides the best performance and reliability.


2. Server-Sent Events (SSE): Server-Sent Events is a unidirectional protocol that allows the server to push data to the client. SSE is a good option for applications where the client only needs to receive data from the server, such as live streaming.


3. Long Polling: Long Polling is a technique that allows the client to keep a connection open with the server until the server has data to send. Long Polling is a good option for applications where the client needs to receive data from the server frequently, but the server may not have data to send all the time.


Persistent connections are important for real-time applications because they allow the server to push data to the client as soon as it becomes available. This makes the applications feel more responsive and engaging.


Here are some of the benefits of using persistent connections in SignalR:

  • Real-time updates: Persistent connections allow the server to push data to the client as soon as it becomes available. This makes the applications feel more responsive and engaging.

  • Low latency: Persistent connections can help to reduce latency, which is the time it takes for data to travel from the client to the server and back. This is important for applications where the user expects a quick response, such as live chat.

  • High throughput: Persistent connections can help to increase throughput, which is the amount of data that can be transferred between the client and the server in a given amount of time. This is important for applications where a lot of data needs to be transferred, such as video streaming.

However, persistent connections also have some drawbacks, such as:

  • Increased bandwidth usage: Persistent connections can increase bandwidth usage, since the connection is always open. This can be a problem for applications that are used by a large number of users.

  • Increased latency: In some cases, persistent connections can actually increase latency, since the server has to keep track of all of the open connections.

  • Security concerns: Persistent connections can pose security concerns, since the connection is always open. This can make it easier for attackers to exploit vulnerabilities in the application.

Choosing the appropriate mode based on application requirements

Here are the factors to consider when choosing the appropriate communication mode for your application:

  • Latency: Latency is the time it takes for data to travel from the client to the server and back. If you need low latency, then WebSockets is the best option.

  • Throughput: Throughput is the amount of data that can be transferred between the client and the server in a given amount of time. If you need high throughput, then WebSockets is also the best option.

  • Support for all browsers: If you need your application to be compatible with all browsers, then Server-Sent Events or Long Polling are good options.

  • Ease of implementation: If you are not familiar with WebSockets, then Server-Sent Events or Long Polling are good options.

  • Security: If you are concerned about security, then WebSockets is the best option.

  • Bandwidth usage: If you are concerned about bandwidth usage, then Long Polling is a good option.

Ultimately, the best communication mode for your application will depend on your specific needs. Consider the factors above and choose the mode that best meets your requirements.


Here are some additional factors to consider:

  • The type of data being transferred: Some data, such as audio and video, requires low latency and high throughput. Other data, such as text messages, can tolerate higher latency.

  • The number of concurrent users: If you expect a large number of concurrent users, then you will need a communication mode that can handle the load. WebSockets is generally the best option for applications with a large number of concurrent users.

  • The network conditions: If the network conditions are not good, then you may need to choose a communication mode that is more tolerant of latency and packet loss. Long Polling is a good option for applications that are used in areas with poor network conditions.


Conclusion

SignalR is a fantastic tool for web development that lets you create websites and apps that can show live updates and work together in real-time. It's like giving your web applications superpowers! Whether you're building a chat app, a live dashboard, or games that people can play together online, SignalR makes it all possible.


By understanding how SignalR works and how to use it with ASP.NET, you can make your websites and apps more exciting and interactive. It's like turning your regular website into a magical place where things happen instantly.

bottom of page