Prerequisites

To follow along, ensure you have the following.

Step 1. Create a New Blazor Server Project

Step 2. Add SignalR Support

SignalR is not included by default in a Blazor Server project, so you need to add it manually.

Open the NuGet Package Manager and install the following package.

Microsoft.AspNetCore.SignalR.Client

Add SignalR services to your project by updating the Program.cs.

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

builder.Services.AddSignalR();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
}

app.UseAntiforgery();

app.MapStaticAssets();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

app.MapHub<ChatHub>("/chathub");

app.Run();

Step 3. Create the SignalR Hub

The Hub is the central point where messages are sent and received in SignalR.

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

This ChatHub class defines a method SendMessage that broadcasts a message to all connected clients.

Step 4. Create the Chat Page

@page "/chat"
@rendermode InteractiveServer

@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager

<h3>Chat Application</h3>

<div>
    <input @bind="UserName" placeholder="Enter your name" />
    <input @bind="MessageInput" placeholder="Enter your message" @onkeypress="SendOnEnter" />
    <button @onclick="SendMessage">Send</button>
</div>

<div style="margin-top: 20px;">
    <h4>Messages:</h4>
    <ul>
        @foreach (var message in Messages)
        {
            <li>@message</li>
        }
    </ul>
</div>

@code {
    private HubConnection? hubConnection;
    private string? UserName;
    private string? MessageInput;
    private List<string> Messages = new();

    protected override async Task OnInitializedAsync()
    {
        // Initialize SignalR connection
        hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
            .Build();

        // Listen to incoming messages
        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            Messages.Add($"{user}: {message}");
            InvokeAsync(StateHasChanged);
        });

        // Start connection
        await hubConnection.StartAsync();
    }

    private async Task SendMessage()
    {
        if (!string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(MessageInput) && hubConnection is not null)
        {
            await hubConnection.SendAsync("SendMessage", UserName, MessageInput);
            MessageInput = string.Empty;
        }
    }

    private async Task SendOnEnter(KeyboardEventArgs e)
    {
        if (e.Key == "Enter")
        {
            await SendMessage();
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (hubConnection is not null)
        {
            await hubConnection.DisposeAsync();
        }
    }
}

This component sets up the user interface and connects to the SignalR hub. It also listens for incoming messages using the ReceiveMessage method and displays them in real-time.

Step 5. Run the Application

Output Below

Output