Real Time Web Apps in .NET
There are a few ways to make a web app real time. You could make a button that refreshes the page, or you could use AJAX to update the page. But what if you want to update the page without the user having to do anything? Well, you could automatically make a request to the server every few seconds using something like setInterval
in JavaScript, but that's not very efficient and it's not very 'real time'.
That's why a lot of people use WebSockets. WebSockets are a new technology that allows you to open a connection between the client and the server and keep it open. This allows the server to send data to the client without the client having to make a request.
To do this we can use a library called SignalR. SignalR is a library for .NET developers that makes it incredibly simple to add real-time web functionality to your applications. It's the ability to have your server-side code push content to the connected clients as it happens, in real-time. If WebSockets are available, SignalR will use them, otherwise it will fall back to other techniques like long polling or server-sent events.
Building a real time web app with SignalR
Let's use an example to demonstrate how SignalR works. We'll create a simple chat application that allows users to send messages to each other in real time.
Start by creating a new ASP.NET Core Web App (MVC), this includes the SignalR library by default. We'll call the project ChatApp
. You can skip the other options for now.
Server Side
Firstly, you should create a new folder called Hubs
and create a new class called ChatHub
inside of it. This class will be used to send messages to the clients. This ChatHub
class should inherit from Hub
, which is imported with using Microsoft.AspNetCore.SignalR
and have a method called SendMessage
that takes two parameters, a string
for the username and a string
for the message.
using Microsoft.AspNetCore.SignalR;
namespace ChatApp.Hubs
{
// Inherit from Hub class in SignalR
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
// Sends an event called "ReceiveMessage" to all clients with the user and message as parameters
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}
We now have created a Hub
that can be connected to by clients. We can now create a client to connect to this Hub
. Before we can actually start using the hub we need to add something to tell the web app to use SignalR. We do this in the Program.cs
file:
// Add SignalR to the web app
builder.Services.AddSignalR();
Now SignalR has been added to the web app, but our hub is not registered yet. We will register our ChatHub
on the url /chathub
. So we do that next in our Program.cs
:
// Add this to the top of the file
using ChatApp.Hubs;
// Add the ChatHub to the app using the "/chat" path
app.MapHub<ChatHub>("/chat");
Client Side
Now we can create a client to connect to this hub. To allow clients to connect, we will need to add the SignalR JavaScript library to our web app. We can do this by adding a new Client Side Library
in Visual Studio. Right click on the wwwroot
folder and click Add
> Client-Side Library...
. Then search for signalr
and install the @microsoft/signalr
package. This will add the SignalR JavaScript library to our web app.

Next we have to add the script to our _Layout.cshtml
file, you can also choose to only add this on the pages that actually need to connect with SignalR.
<!-- Add SignalR -->
<script src="~/microsoft-signalr/signalr.min.js"></script>
Now we can create a new JavaScript file called chat.js
in the wwwroot/js
folder. This file will contain the code to connect to the hub and send messages to it. We will also add a function to receive messages from the hub.
"use strict"; // Use strict mode so we get errors if we make dumb mistakes
// Create a connection to the hub, using the "/chat" path that we registered in the Program.cs file
const connection = new signalR.HubConnectionBuilder().withUrl("/chat").build();
// Start the connection
connection.start().catch(function (err) {
// If there is an error, log it to the console
return console.error(err.toString());
});
// Add a function to run when we receive a message from the hub
connection.on("ReceiveMessage", function (user, message) {
// Create a message with the user and message
var msg = user + " says: " + message;
// Create a new list item with the message and add it to the list of messages
var li = document.createElement("li");
li.textContent = msg;
document.getElementById("messagesList").appendChild(li);
});
// Add a function to send messages to the hub when the send button is clicked
document
.getElementById("sendButton")
.addEventListener("click", function (event) {
// Get the user and message from the input fields
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
// Send the message to the hub
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
This code will connect to the hub and send messages to it. It will also add a function to receive messages from the hub and add them to the list of messages. Now add this script to the _Layout.cshtml
file:
<script src="~/js/chat.js"></script>
Now we can add the HTML to our Index.cshtml
file to display the messages and send messages to the hub. Don't forget to add the id
attributes to the elements so we can select them in our JavaScript file. You can also add some CSS to make it look nice, in this example we will use the included Bootstrap CSS.
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h3>Chat</h3>
</div>
<div class="card-body">
<!-- Our messages will be shown here -->
<ul id="messagesList"></ul>
</div>
<div class="card-footer">
<div class="input-group">
<!-- We will get our username and message from these fields -->
<input
type="text"
id="userInput"
class="form-control"
placeholder="Username"
/>
<input
type="text"
id="messageInput"
class="form-control"
placeholder="Message"
/>
<div class="input-group-append">
<!-- When this button is clicked, we will send a message to the server -->
<button id="sendButton" class="btn btn-primary">Send</button>
</div>
</div>
</div>
</div>
</div>
</div>
Testing
That was it! Now we can run our web app and test it out. You can open the web app in multiple tabs to test it out. You should see something like this:

Conclusion
After following this tutorial you should have a basic understanding of how SignalR works and how you can use it in your own projects. For more info about SignalR, check out the official documentation by Microsoft.