Building Real-Time Web Apps with SignalR, WebAssembly, and ASP.NET Core API
Have you ever worked on a chat application where you need to display messages in real-time or on applications that need to reflect changes based on backend updates? One common method used previously is polling the backend for changes at specific intervals. However, this approach is not ideal as it slows down the client-side application and increases traffic on the backend. One solution to this problem is SignalR.
In this blog, we’ll explore how to build a real-time web application using three cutting-edge technologies: SignalR, WebAssembly, and ASP.NET Core API. SignalR simplifies the process of adding real-time web functionality, WebAssembly brings near-native performance to web apps, and ASP.NET Core API provides a robust and scalable backend. By combining these technologies, you can create web applications that are both highly responsive and performant.
What is SignalR?
SignalR is a library for ASP.NET that enables real-time web functionality. It allows server-side code to push content to connected clients instantly as it becomes available. SignalR supports multiple communication protocols, including WebSockets, and automatically falls back to other compatible protocols for older browsers. This makes it an excellent choice for applications that require high-frequency updates, like chat applications, gaming, or live data feeds.
Setting Up the ASP.NET Core API
Create a New ASP.NET Core Project
First, create a new ASP.NET Core Web API project. Open your terminal or command prompt and run the following command:
dotnet new webapi -n RealTimeApp
This command creates a new ASP.NET Core Web API project named RealTimeApp
.
Install SignalR
Next, navigate to the project directory and install the SignalR package:
cd RealTimeApp
dotnet add package Microsoft.AspNetCore.SignalR
Configure SignalR in program.cs
Open the program.cs
file and configure SignalR. Your program.cs
file should look like this:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder =>
{
builder.WithOrigins("http://localhost:5051")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
builder.Services.AddControllers();
// Adding SignalR
builder.Services.AddSignalR();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseRouting();
// Adding the endpoint for the ChatHub
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chatHub");
});
app.Run();
Create the SignalR Hub
Create a new class called ChatHub.cs
in the project and define the SendMessage
method:
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Integrating WebAssembly
Create a New Blazor WebAssembly Project
First, create a new Blazor WebAssembly project. Open your terminal or command prompt and run the following command:
dotnet new blazorwasm -n RealTimeApp.Client
This command creates a new Blazor WebAssembly project named RealTimeApp.Client
.
Add SignalR Client Library
Navigate to the project directory and add the SignalR client library:
cd RealTimeApp.Client
dotnet add package Microsoft.AspNetCore.SignalR.Client
Create the Blazor Component
Create a new Razor component for the chat interface. You can name it Chat.razor
.
Add the following content to Chat.razor
:
"/chat"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
<h3>Chat</h3>
<input @bind="userInput" placeholder="Your name" class="form-control" />
<br>
<input @bind="messageInput" placeholder="Your message" @onkeypress="@(e => { if (e.Key == "Enter") Send().GetAwaiter().GetResult(); })" class="form-control" />
<br>
<div style="text-align: right">
<button @onclick="Send" class="btn btn-primary">Send</button>
</div>
<ul>
@foreach (var message in messages)
{
<li>@message</li>
}
</ul>
@code {
private HubConnection hubConnection;
private string userInput;
private string messageInput;
private List<string> messages = new List<string>();
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl("http://localhost:5258/chathub")
.Build();
hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
messages.Add(encodedMsg);
InvokeAsync(StateHasChanged);
});
await hubConnection.StartAsync();
}
private async Task Send()
{
await hubConnection.SendAsync("SendMessage", userInput, messageInput);
messageInput = string.Empty;
}
}
Add Navigation to Chat.razor
Ensure your Chat.razor
component can be accessed via navigation. Update your NavMenu.razor
file to include a link to the chat component:
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" href="chat">
<span class="oi oi-chat" aria-hidden="true"></span> Chat
</NavLink>
</li>
</ul>
Run the Application
Run the ASP.NET Core API:
dotnet run --project RealTimeApp
Run the Blazor WebAssembly app:
dotnet run --project RealTimeApp.Client
Navigate to /chat
in your Blazor WebAssembly app to see the chat interface. You should be able to send messages, which will be broadcasted to all connected clients in real-time using SignalR.
Conclusion
In this blog, we’ve explored how to build a real-time web application using SignalR, WebAssembly, and ASP.NET Core API. By leveraging these technologies, we created a responsive chat application capable of instant updates without the need for constant polling. SignalR facilitated real-time communication, WebAssembly provided near-native performance, and ASP.NET Core API served as a robust backend.
We started by setting up an ASP.NET Core API and integrating SignalR to handle real-time messages. Then, we created a Blazor WebAssembly client that interacts with the SignalR hub to send and receive messages. This combination of technologies not only enhances performance but also simplifies the development of real-time web applications.
I hope this tutorial has provided you with a solid foundation for building your own real-time applications. To see the complete source code and explore further, visit the GitHub repository: GitHub Repository: RealTimeApp
Feel free to clone the repository, experiment with the code, and extend the application to suit your needs.
To explore more on this topic, you can check out the following resources:
Happy coding!