Add SignalR integration for real-time weather updates

Implemented SignalR to enable real-time communication between the server and connected clients. Added a new hub (`WeatherUpdateHub`), a background service (`SignalRSendService`), and modified both the API backend and React frontend for seamless message broadcasting and handling.
This commit is contained in:
2025-02-06 22:21:53 +01:00
parent 892b2183e0
commit be2599218d
12 changed files with 202 additions and 15 deletions

View File

@@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.2.0" />
<PackageReference Include="NSwag.AspNetCore" Version="14.2.0" />
</ItemGroup>

View File

@@ -1,9 +1,13 @@
using Api.SignalR;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddOpenApi();
builder.Services.AddSignalR();
builder.Services.AddHostedService<SignalRSendService>();
builder.Services.AddOpenApiDocument(config =>
{
config.Title = "NSwag Demo API";
@@ -12,9 +16,10 @@ builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyOrigin()
policy.WithOrigins("http://localhost:3000") // Specify the allowed origin
.AllowAnyHeader()
.AllowAnyMethod();
.AllowAnyMethod()
.AllowCredentials(); // Allow credentials
});
});
@@ -36,7 +41,7 @@ var summaries = new[]
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
app.MapGet("/weatherforecast", () =>
app.MapGet("/weatherforecast", async () =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
@@ -46,10 +51,15 @@ app.MapGet("/weatherforecast", () =>
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
})
.WithName("GetWeatherForecast");
// Add SignalR hub
app.MapHub<WeatherUpdateHub>("/WeatherUpdateHub");
app.Run();
record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)

View File

@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.SignalR;
namespace Api.SignalR
{
public class SignalRSendService(IHubContext<WeatherUpdateHub> hubContext, ILogger<SignalRSendService> logger) : BackgroundService
{
#region Override ExecuteAsync
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// For example, wait 10 seconds between messages.
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
// Log or do any work here.
logger.LogInformation("Background service sending message at: {Time}", DateTime.Now);
// Send a message to all connected clients.
await hubContext.Clients.All.SendAsync(
"ReceiveMessage", // This is the client method name.
"Background Service", // Example sender.
"Hello from the background task!", // The message.
stoppingToken);
}
}
#endregion
}
}

View File

@@ -0,0 +1,14 @@
using Microsoft.AspNetCore.SignalR;
namespace Api.SignalR
{
public class WeatherUpdateHub: Hub
{
// This method can be called by connected clients.
public async Task SendMessage(string user, string message)
{
// Broadcast the message to all connected clients.
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
}