Real-Time Web Applications with SignalR and .NET: A Hands-On Guide
Asharib Kamal
Sr. Full Stack Developer | Specializing in .NET Technologies | C# | Dot NET Core | Asp.NET MVC | Angular | SQL | Content Creator | Transforming Ideas into High-Impact Web Solutions | 7K + Followers
Real-time web applications are becoming increasingly popular, enabling instant communication and dynamic data updates between clients and servers. SignalR is a powerful library in .NET that simplifies adding real-time functionalities to your web applications. In this hands-on guide, we will explore the features, benefits, and implementation of SignalR in .NET, along with code examples to help you get started.
?
?What is SignalR?
?
SignalR is a library for ASP.NET that enables real-time web functionalities by allowing server-side code to push content to connected clients instantly. It supports various transport methods, including WebSockets, Server-Sent Events, and Long Polling, ensuring compatibility across different browsers and environments.
?
?Key Features of SignalR
?
- Real-Time Communication: Enables real-time bi-directional communication between server and client.
- Automatic Reconnection: Handles connection interruptions and automatically attempts to reconnect.
- Scalability: Can be scaled out using Redis, SQL Server, or Azure Service Bus.
- Transport Fallback: Automatically selects the best available transport method based on client and server capabilities.
?
?Benefits of Using SignalR
?
- Improved User Experience: Provides instant updates and reduces latency.
- Simplified Development: Abstracts the complexity of real-time communication.
- Cross-Platform Support: Compatible with various clients, including web, mobile, and desktop applications.
- Extensibility: Can be integrated with other technologies and platforms for enhanced functionality.
?
?Getting Started with SignalR in .NET
?
?Setting Up Your Environment
?
Before we begin, ensure you have the following installed:
?
- .NET SDK
- Visual Studio or Visual Studio Code
?
?Creating a SignalR Hub
?
1. Create a new ASP.NET Core project:
?
??? dotnet new web -n RealTimeApp
cd RealTimeApp??
?
2. Add the SignalR package:
?
???dotnet add package Microsoft.AspNetCore.SignalR??
?
3. Create the SignalR Hub:
// Hubs/ChatHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}?
?
领英推荐
4. Configure SignalR in Startup.cs:
?
??? // Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapHub<ChatHub>("/chathub");
});
}?
?Creating the Client
?
1. Add SignalR JavaScript client library:
?
??? Add the following script to your HTML file:
?
??? <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/5.0.7/signalr.min.js"></script>
?
2. Create the client-side JavaScript:
?
???<!-- wwwroot/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Real-Time Chat</title>
</head>
<body>
<div>
<input type="text" id="userInput" placeholder="Username" />
<input type="text" id="messageInput" placeholder="Message" />
<button onclick="sendMessage()">Send</button>
</div>
<ul id="messagesList"></ul>
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chathub")
.build();
connection.on("ReceiveMessage", (user, message) => {
const li = document.createElement("li");
li.textContent = ${user}: ${message};
document.getElementById("messagesList").appendChild(li);
});
connection.start().catch(err => console.error(err.toString()));
function sendMessage() {
const user = document.getElementById("userInput").value;
const message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString()));
}
</script>
</body>
</html>
?
?Running the Application
?
1. Run the application:
?
??? dotnet run??
?
2. Open your browser and navigate to the application URL:
?
??? Open multiple tabs or windows to see the real-time communication in action.
?
?Daily Life Example: Real-Time Stock Price Updates
?
Consider a financial trading platform where users need to see real-time updates of stock prices. Using SignalR, the server can push updates to all connected clients instantly, ensuring users have the latest information without refreshing the page.
?
?StockHub Example
?
1. Create a StockHub:
?
??? // Hubs/StockHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
public class StockHub : Hub
{
public async Task UpdateStockPrice(string stock, decimal price)
{
await Clients.All.SendAsync("ReceiveStockPrice", stock, price);
}
}?
2. Simulate stock price updates:
?
?// Controllers/StockController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
[ApiController]
[Route("[controller]")]
public class StockController : ControllerBase
{
private readonly IHubContext<StockHub> _hubContext;
public StockController(IHubContext<StockHub> hubContext)
{
_hubContext = hubContext;
}
[HttpGet("update")]
public async Task<IActionResult> Update()
{
Random random = new Random();
string stock = "AAPL";
decimal price = random.Next(100, 150);
await _hubContext.Clients.All.SendAsync("ReceiveStockPrice", stock, price);
return Ok(new { stock, price });
}
}
?
3. Client-side script for receiving updates:
?
??? <!-- wwwroot/index.html -->
<script>
const connection = new signalR.HubConnectionBuilder()
.withUrl("/stockhub")
.build();
connection.on("ReceiveStockPrice", (stock, price) => {
const li = document.createElement("li");
li.textContent = ${stock}: $${price};
document.getElementById("stocksList").appendChild(li);
});
connection.start().catch(err => console.error(err.toString()));
</script> ?