Real-Time Communication with ASP.NET Core and SignalRe

tamami.I Web Developer
6 min readJan 20, 2025

1. Scope of This Article

SignalR is a library included in ASP.NET Core that simplifies implementing real-time communication in web applications. This article introduces sample code for a chat application built with SignalR and explains its underlying mechanisms and key technical points.

2. What is SignalR?

Features

SignalR is a library that facilitates real-time communication between clients and servers. Its primary advantage lies in its ability to automatically select the most suitable persistent connection model based on the environment:

WebSockets: A high-speed and efficient protocol that enables bidirectional communication between the client and server.

Server-Sent Events (SSE): Utilizes the HTTP protocol to enable unidirectional communication from the server to the client.

Long Polling: Maintains communication by repeatedly sending HTTP requests when WebSockets or SSE are unavailable.

How SignalR Works

SignalR reduces the burden on developers by automatically selecting the appropriate protocol for communication. This process involves the following steps:

Negotiation Phase:

  • The client sends a connection request to the server, which negotiates the best available protocol.
  • Examples: If WebSockets are supported, they are prioritized.If not, it falls back to SSE, and if SSE is unavailable, Long Polling is used.

Connection Management:

  • SignalR detects connection interruptions and automatically attempts to reconnect (e.g., in case of temporary network issues).
  • Once reconnected, SignalR resumes the interrupted communication seamlessly.

Message Transmission:

  • Messages sent between the server and client are serialized in either JSON or MessagePack format.
  • Using MessagePack reduces the data payload size, resulting in improved performance.

Bidirectional Communication with SignalR

SignalR enables seamless bidirectional communication between servers and clients by providing the following features:

Broadcasting:

  • The server sends messages to all connected clients.
  • Example: A “notify all” feature in a chat application.

Group Messaging:

  • Clients can be grouped, allowing messages to be sent only to specific groups.
  • Example: Sending messages within a particular chat room.

Direct Messaging:

  • Messages can be sent to specific clients using their Connection ID.
  • Example: Implementing a private chat feature.

3. Sample Implementation

3–1. Overview of the Sample

This sample demonstrates how to build a simple real-time chat application using SignalR, featuring the following key functionalities:

Real-Time Messaging:

  • Enables real-time message exchange between clients.
  • Supports direct messaging between users.

Member List:

  • Displays currently online users.
  • Allows users to select a chat partner by clicking on their name.

Intuitive UI/UX:

  • Provides a clean and user-friendly layout with separate sections for the member list and chat area.

SignalR’s Automatic Fallback Mechanism:

  • Automatically selects the optimal protocol based on the environment, ensuring stable communication.

This implementation serves as a foundational example that can be extended for more complex real-time communication scenarios.

3–2. Implementation Structure

Architecture

Backend:

  • Built with ASP.NET Core, the SignalR hub manages client-to-client communication efficiently.

Frontend:

  • Utilizes JavaScript to leverage the SignalR client library for seamless communication with the server.
  • Implements a clean and intuitive chat UI using HTML and CSS.

This structure ensures a clear separation of responsibilities, making the implementation modular, maintainable, and extendable.

3–3. Code Explanation

https://github.com/supino0017/signalr-chat-sample

3–3–1. Adding the SignalR Client Library

While the SignalR server library is included in the ASP.NET Core shared framework, the JavaScript client library must be added to the project manually. Follow the steps below to include the client library:

Using the Library Manager (LibMan)

Retrieve the SignalR client library from unpkg by running the following command:

libman install @microsoft/signalr --provider unpkg

Once installed, the client library will be available in your project and can be used to enable communication with the SignalR server.

This library is essential for establishing and managing the connection between the client and the SignalR hub. It simplifies sending and receiving real-time messages, making it a vital component of the chat application’s frontend.

3–3–2. Configuring the SignalR Server

To ensure SignalR requests are correctly handled, you need to configure SignalR within your ASP.NET Core application. Add the following code to the 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");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

Key Configurations

builder.Services.AddSignalR();

  • Adds the SignalR service to ASP.NET Core’s dependency injection system. This enables the application to utilize SignalR’s features.

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

  • Defines the SignalR hub endpoint. Clients will communicate with the server via /chatHub.

How It Works

  • SignalR Service Registration: The AddSignalR method integrates SignalR into the application. This allows the app to handle real-time communication requests.
  • Endpoint Mapping: By mapping the ChatHub to /chatHub, the application designates a specific route for SignalR communications. Clients can connect to this endpoint to send and receive messages.

This configuration ensures that SignalR is fully integrated into ASP.NET Core’s routing system, enabling seamless real-time communication in your application.

3–3–3. Creating the SignalR Hub

A hub is a high-level pipeline that facilitates communication between clients and the server. Follow these steps to create a hub:

Create a Hubs Folder:

  • Inside the project directory, create a folder named Hubs.

Create the ChatHub Class:

  • In the Hubs folder, create a class named ChatHub that inherits from SignalR's Hub class.

Below is an example implementation of the ChatHub class:

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

public class ChatHub : Hub
{
public async Task SendMessage(string sender, string receiver, string message)
{
// Log message sending
Console.WriteLine($"[SendMessage] {sender} -> {receiver}: {message}");

// Send the message only to the recipient
await Clients.Group(receiver).SendAsync("ReceiveMessage", sender, message);
}

public override async Task OnConnectedAsync()
{
var username = Context.GetHttpContext()?.Request.Query["username"];
if (!string.IsNullOrEmpty(username))
{
// Add user to a group
Console.WriteLine($"[OnConnected] User connected: {username}");
await Groups.AddToGroupAsync(Context.ConnectionId, username);
}
await base.OnConnectedAsync();
}

public override async Task OnDisconnectedAsync(Exception? exception)
{
var username = Context.GetHttpContext()?.Request.Query["username"];
if (!string.IsNullOrEmpty(username))
{
// Remove user from a group
Console.WriteLine($"[OnDisconnected] User disconnected: {username}");
await Groups.RemoveFromGroupAsync(Context.ConnectionId, username);
}
await base.OnDisconnectedAsync(exception);
}
}

Key Methods

SendMessage:

  • Sends a message from the sender to a specific recipient.
  • Uses Clients.Group to target the message to a particular group.

OnConnectedAsync:

  • Triggered when a client connects to the hub.
  • Adds the connected user to a group based on their username.

OnDisconnectedAsync:

  • Triggered when a client disconnects from the hub.
  • Removes the user from the group they were previously added to.

How It Works

  1. When a user connects to the hub, their username (passed via query parameters) is used to assign them to a group.
  2. The SendMessage method allows one user to send messages specifically to another user by referencing their group name.
  3. Upon disconnection, the user is removed from the group, ensuring that their session is properly managed.

This implementation provides a foundation for building more complex real-time communication features, such as group chats or private messaging.

3–3–4. Client-Side Implementation

On the client side, JavaScript is used to establish a connection with the SignalR server. Below is the basic client-side code example:

const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub?username=YourUsername")
.build();

connection.on("ReceiveMessage", (sender, message) => {
console.log(`Message from ${sender}: ${message}`);
});

connection.start()
.then(() => console.log("Connected to SignalR server."))
.catch(err => console.error("Connection error:", err));

function sendMessage(receiver, message) {
connection.invoke("SendMessage", "YourUsername", receiver, message)
.catch(err => console.error("Send error:", err));
}

How the Client Works

Connection Establishment:

  • The client connects to the SignalR hub and sends its username via query parameters.
  • The server uses the username to register the user in a group for targeted messaging.

Sending Messages:

  • When a message is sent, the client invokes the SendMessage method on the server, specifying the sender, recipient, and message content.
  • The server routes the message to the specified recipient’s group.

Receiving Messages:

  • The client listens for the ReceiveMessage event, triggered by the server when a message is sent to the client's group.
  • Received messages are displayed in real-time in the chat interface.

4. Conclusion

SignalR is a powerful tool for efficiently building the foundation of applications requiring real-time communication. Its flexibility and automatic protocol selection capabilities make it suitable for a wide range of use cases. By leveraging SignalR, developers can simplify the complexities of real-time communication logic, significantly reducing development time and costs. Additionally, its group management and protocol selection features enable scalable and extensible application designs tailored to various scenarios and requirements.

--

--

tamami.I Web Developer
tamami.I Web Developer

Written by tamami.I Web Developer

I’m an engineer from Japan who loves coffee and mystery novels. I focus on cloud-native tech and share insights on tips, reflections, and hobbies.

No responses yet