DEV Community

Maria
Maria

Posted on

Building Real-Time Applications with SignalR and C#

Building Real-Time Applications with SignalR and C

In the ever-evolving world of web development, real-time capabilities are no longer just a luxury—they’ve become an essential feature of many modern applications. Whether you’re building a live chat system, a stock price tracker, or a multiplayer game, users expect instantaneous updates without refreshing the page. Enter SignalR, a powerful library that makes real-time communication in .NET applications not only possible but also surprisingly simple.

In this blog post, we’ll explore how to build interactive, real-time web applications using SignalR and C#. We’ll dive into WebSockets, data streaming, and creating responsive user experiences. By the end, you’ll have a solid foundation to start building your own real-time applications.


What is SignalR?

At its core, SignalR is a library for ASP.NET Core that simplifies adding real-time web functionality to your applications. It allows the server to push updates to connected clients as soon as they’re available, instead of requiring the client to poll the server for updates.

Think of SignalR as a phone call between the client and the server. Instead of repeatedly checking if there’s new information (like sending text messages back and forth), the server can speak directly to the client whenever there’s something important to share.


Why Use SignalR?

Before diving into the technical details, let’s understand why SignalR is such a game-changer:

  1. Real-Time Communication: SignalR allows you to create applications where clients receive updates almost instantaneously.
  2. Simplified WebSocket Management: It abstracts the complexities of WebSockets while also falling back to other techniques (like Server-Sent Events or Long Polling) if WebSockets aren’t supported.
  3. Scalable: SignalR can be integrated with distributed systems using backplanes like Azure SignalR Service or Redis.
  4. Cross-Platform: SignalR works seamlessly with both .NET and JavaScript applications.

How SignalR Works Under the Hood

SignalR uses a transport fallback mechanism to maintain a persistent connection between the server and the client:

  1. WebSockets: The default and most efficient protocol.
  2. Server-Sent Events (SSE): Used if WebSockets aren’t supported.
  3. Long Polling: A fallback mechanism that continuously polls the server for updates.

Thanks to this fallback system, SignalR ensures robust real-time communication in diverse environments.


Setting Up SignalR in Your Project

Let’s dive into the code! For this tutorial, we’ll create a simple chat application where users can send and receive messages in real time.

Prerequisites

Ensure you have the following installed:

  • .NET 7 SDK
  • Node.js (optional, for running front-end code)
  • A text editor or IDE like Visual Studio or Visual Studio Code

Step 1: Create a New ASP.NET Core Web Application

Start by creating a new ASP.NET Core web project:

dotnet new web -n SignalRChatApp
cd SignalRChatApp
Enter fullscreen mode Exit fullscreen mode

Next, add the SignalR NuGet package:

dotnet add package Microsoft.AspNetCore.SignalR
Enter fullscreen mode Exit fullscreen mode

Step 2: Build the SignalR Hub

A hub is the central component in SignalR that acts as a communication bridge between clients and the server. Let’s create a hub for our chat application.

Create a new file named ChatHub.cs in the project directory:

using Microsoft.AspNetCore.SignalR;

public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        // Broadcast the message to all connected clients
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
Enter fullscreen mode Exit fullscreen mode

Here’s what’s happening:

  • The ChatHub inherits from Hub, which is SignalR’s base class for real-time communication.
  • The SendMessage method takes a user and message as parameters and broadcasts them to all connected clients using Clients.All.SendAsync.

Step 3: Configure SignalR in the ASP.NET Core App

Update the Program.cs file to configure SignalR:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

// Add SignalR services
builder.Services.AddSignalR();

// Map the SignalR hub
app.MapHub<ChatHub>("/chatHub");

// Serve static files (if using a front-end)
app.UseStaticFiles();

app.Run();
Enter fullscreen mode Exit fullscreen mode

This code does two things:

  1. Adds SignalR services to the dependency injection container.
  2. Maps the ChatHub to the /chatHub endpoint.

Step 4: Create the Front-End Client

For simplicity, we’ll use plain HTML and JavaScript to connect to the SignalR hub. Create an index.html file in the wwwroot folder:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SignalR Chat</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.5/signalr.min.js"></script>
</head>
<body>
    <h1>SignalR Chat</h1>
    <input id="userInput" type="text" placeholder="Your name" />
    <input id="messageInput" type="text" placeholder="Your message" />
    <button id="sendButton">Send</button>
    <ul id="messagesList"></ul>

    <script>
        // Connect to the SignalR hub
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("/chatHub")
            .build();

        // Start the connection
        connection.start()
            .catch(err => console.error(err.toString()));

        // Handle incoming messages
        connection.on("ReceiveMessage", (user, message) => {
            const li = document.createElement("li");
            li.textContent = `${user}: ${message}`;
            document.getElementById("messagesList").appendChild(li);
        });

        // Send messages
        document.getElementById("sendButton").addEventListener("click", () => {
            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>
Enter fullscreen mode Exit fullscreen mode

Step 5: Run the Application

Run the application using the following command:

dotnet run
Enter fullscreen mode Exit fullscreen mode

Open the app in your browser, and you’ll be able to send and receive real-time messages!


Common Pitfalls and How to Avoid Them

  1. Connection Errors: Ensure the SignalR hub endpoint (/chatHub) matches between the client and server configurations.
  2. Unsupported WebSockets: Test your application in environments with limited WebSocket support. SignalR will fall back to other protocols, but you should verify behavior in all target environments.
  3. Scalability Issues: For production environments with multiple servers, configure a backplane (like Redis or Azure SignalR Service) to distribute messages efficiently.
  4. Error Handling: Always handle errors gracefully on both the client and server sides to avoid unexpected crashes.

Key Takeaways

  • SignalR simplifies the process of building real-time applications in .NET.
  • It abstracts complex communication protocols like WebSockets, making it accessible to developers.
  • The combination of a SignalR hub and client-side JavaScript enables seamless bidirectional communication.
  • Always consider scalability and error handling when deploying SignalR applications to production.

Next Steps

If you’re ready to take your SignalR skills to the next level, here are a few ideas:

  1. Dive Deeper into WebSockets: Learn about the underlying protocol for optimal performance.
  2. Explore Scaling Options: Set up a Redis backplane or experiment with Azure SignalR Service.
  3. Build Advanced Features: Add typing indicators, private messaging, or authentication to your chat app.

Real-time applications are no longer a challenge with SignalR. So, what will you build next? Let us know in the comments below! 🚀

Top comments (0)