Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
Aug 19

Building real-time notifications in .NET Core 8 Minimal APIs using SignalR

Building real-time notifications in .NET Core 8 Minimal APIs using SignalR
Автор:
Источник:
Просмотров:
1110

Introduction

Building real-time applications has become essential in modern web development, especially for features like notifications, chat systems, and live updates. SignalR, a powerful library for ASP.NET, enables seamless real-time communication between server-side code and client-side web applications. In this guide, we’ll walk through creating real-time notifications in .NET Core 8 using Minimal APIs and SignalR, ensuring your applications stay responsive and engaging.

Why use SignalR?

  • Real-Time communication: It enables real-time updates, which is crucial for modern, dynamic applications such as chat systems, gaming, live sports updates, and collaborative applications.
  • Simplified development: SignalR provides a simple API that abstracts the complexities of real-time communications, making it easier for developers to implement these features.
  • Cross-platform: SignalR supports multiple platforms, including .NET, JavaScript, and Xamarin, allowing for broad applicability across different types of applications.
  • Automatic reconnection: SignalR handles automatic reconnection in case of a dropped connection, ensuring the reliability of real-time communication.
  • Scalability: SignalR is scalable and can be used in conjunction with other services like Azure SignalR Service, which handles the scale-out needs and provides high availability.

Creating a SignalR server

Installation

First, let’s install the SignalR package. You can do this via the NuGet Package Manager Console in Visual Studio with the following command:

Install-Package Microsoft.AspNetCore.SignalR

Alternatively, you can install it using the NuGet Package Manager UI by searching for “Microsoft.AspNetCore.SignalR”.

Microsoft.AspNetCore.SignalR

Create ASP.Net Core Web API project

Step 1

Open Visual Studio and click on Create New Project.

Step 2

Select ASP.NET Core Web API Template as shown in the below image and click on next button.

ASP.NET Core Web API

Step 3

Configure your project by specifying the name of the project and the location where you want to save your project.

Configure your new project

Step 4

Select the version of the .Net Core framework you want to use and click on create button.

Additional information

Step 5

Go to Program.cs and add service for SignalR.

builder.Services.AddSignalR();

Step 6

Add class StockHub.cs

using Microsoft.AspNetCore.SignalR;
namespace SignalRWebAPI
{
    public class StockHub:Hub
    {
        public async Task SendStockPrice(string stockName, decimal price)
        {
            await Clients.All.SendAsync("ReceiveStockPrice", stockName, price);
        }
        public override async Task OnConnectedAsync()
        {
            string connectionId = Context.ConnectionId;
            await base.OnConnectedAsync();
        }
    }
}

Step 7

Go to Program.cs and map the stockHub

app.MapHub<StockHub>("/hubs/stock");

Step 8

Background Service to push notifications continuously.

Add class Worker.cs

using Microsoft.AspNetCore.SignalR;

namespace SignalRWebAPI
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private readonly IHubContext<StockHub> _stockHub;
        private const string stockName = "Basic Stock Name";
        private decimal stockPrice = 100;

        public Worker(ILogger<Worker> logger, IHubContext<StockHub> stockHub)
        {
            _logger = logger;
            _stockHub = stockHub;
        }
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

                    Random rnd = new Random();
                    decimal stockRaise = rnd.Next(1, 10000);
                    //List of stock names
                    string[] stockNames = { "Apple", "Microsoft", "Google", "Amazon", "Facebook" };
                    //Random stock name
                   var stockName = stockNames[rnd.Next(0, stockNames.Length)];
                    //Send Notification
                    await _stockHub.Clients.All.SendAsync("ReceiveStockPrice", stockName, stockRaise);

                    _logger.LogInformation("Sent stock price: {stockName} - {stockRaise}", stockName, stockRaise);

                    await Task.Delay(4000, stoppingToken);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error sending stock price");
                }
            }
        }
    }
}

Add this background service in Program.cs

builder.Services.AddHostedService<Worker>();

SignalR Receiver

Server Side

Add new console project separately or with in the same solution file.

Solution SignalRWebAPI

Remove all code from Program.cs of console app and past the below code.

using Microsoft.AspNetCore.SignalR.Client;

// here is SignalR Sender URL
string hubUrl = "https://localhost:7091/hubs/stock";
var hubConnection = new HubConnectionBuilder()
    .WithUrl(hubUrl)
    .Build();

// Register a handler for messages from the SignalR hub
// "ReceiveStockPrice" is the topic to which SignalR sending the singnals
hubConnection.On<string, decimal>("ReceiveStockPrice", (stockName, stockPrice) =>
{
    Console.WriteLine($"Message received--> Stock Name: {stockName} Stock Price: {stockPrice}");
});

try
{
    // Start the connection
    hubConnection.StartAsync().Wait();
    Console.WriteLine("SignalR connection started.");
}
catch (Exception ex)
{
    Console.WriteLine($"Error connecting to SignalR: {ex.Message}");
    throw;
}
// Create a cancellation token to stop the connection
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();

// hubConnection.StopAsync().Wait();
var cancellationToken = cancellationTokenSource.Token;

// Handle Ctrl+C to gracefully shut down the application
Console.CancelKeyPress += (sender, a) =>
{
    a.Cancel = true;
    Console.WriteLine("Stopping SignalR connection...");
    cancellationTokenSource.Cancel();
};
try
{
    // Keep the application running until it is cancelled
    await Task.Delay(Timeout.Infinite, cancellationToken);
}
catch (TaskCanceledException)
{
}
// Stop the connection gracefully
await hubConnection.StopAsync();

Console.WriteLine("SignalR connection closed.");

Solution property

Client side

Index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SignalR Client</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.18/signalr.min.js"></script>
</head>
<body>
    <h1>Stock Prices</h1>
    <div id="stockPrices"></div>

    <script>
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("https://localhost:7091/hubs/stock")
            .build();

        connection.on("ReceiveStockPrice", (stockName, stockPrice) => {
            const stockPricesDiv = document.getElementById("stockPrices");
            const newPrice = document.createElement("div");
            newPrice.textContent = `Stock received: ${stockName} - ${stockPrice}`;
            stockPricesDiv.appendChild(newPrice);
        });

        connection.start()
            .then(() => {
                console.log("SignalR connection started.");
            })
            .catch(err => {
                console.error("Error connecting to SignalR: ", err);
            });

        window.addEventListener("beforeunload", () => {
            connection.stop().then(() => {
                console.log("SignalR connection stopped.");
            }).catch(err => {
                console.error("Error stopping SignalR connection: ", err);
            });
        });
    </script>
</body>
</html>

Now receiving notifications both on Web and console App.

Receiving notifications

Implementing a Real-Time Notification Endpoint

app.MapPost("sendStockNotification", async (
    string stockName,
    decimal price,
    IHubContext<StockHub> context) =>
{
    await context.Clients.All.SendAsync("ReceiveStockPrice", stockName, price);
});

When a client sends a POST request to the sendStockNotification endpoint with the stock name and price, this code will broadcast the stock price update to all connected clients in real time. The clients will receive this update through the "ReceiveStockPrice" method, which they have subscribed to.

Happy coding!

I hope you find this article helpful. You can download source code from my GitHub

Файлы

Похожее
Jul 25
Author: Ankit Sahu
Introduction In this article, we are going to discuss How to implement Authentication and Authorization in .NET 8 Web API. This is a continuation of.Net 8 series, so if you are new, Please have a look at my previous articles....
Jun 26, 2021
SignalR is a popular software library that allows you send server code to client-side applications, like a React application. This tutorial will show you how to install SignalR on both your ASP.NET Core and React Typescript application. Creating your Applications...
May 2
Author: Ankit Sahu
...
Feb 29
Author: Sharmila Subbiah
Introduction With the release of .NET 8, Microsoft takes a significant stride forward, introducing the native Ahead-of-Time (AOT) compilation for ASP.NET Core. This advancement not only enhances application performance but also simplifies the development process, marking a new era in...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Четыре типажа программистов
Performance review, ачивки и погоня за повышением грейда — что может причинить боль сотруднику IT-компании?
GraphQL решает кучу проблем — рассказываем, за что мы его любим
Разбираемся с middleware в ASP.NET Core
Как избавиться от прокрастинации до того, как она разрушит вашу карьеру
Функции и хранимые процедуры в PostgreSQL: зачем нужны и как применять в реальных примерах
Разрабы работают медленно и дорого — и люди считают нас лентяями. Просто в разработке всё сложно
Using a сustom PagedList class for Generic Pagination in .NET Core
Интернет вещей — а что это?
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile