SignalR (Temps réel)
SignalR est une bibliothèque pour ASP.NET Core qui permet d’ajouter des fonctionnalités web en temps réel aux applications.
Pourquoi SignalR ?
Le protocole HTTP classique fonctionne sur le principe Requête -> Réponse. Le client demande, le serveur répond. Si le serveur a une nouvelle information (ex: nouveau message de chat), il ne peut pas l’envoyer directement au client. Le client doit refaire une demande (Polling).
SignalR permet au serveur d’envoyer du contenu aux clients connectés instantanément (Push).
Il utilise sous le capot la meilleure technique de transport disponible :
- WebSockets (Le plus performant, connexion bidirectionnelle persistante).
- Server-Sent Events (SSE).
- Long Polling (Solution de repli).
Le Hub
Le cœur de SignalR est le Hub. C’est une classe qui sert de pipeline de haut niveau pour gérer les communications client-serveur.
Création du Hub
using Microsoft.AspNetCore.SignalR;
public class ChatHub : Hub
{
// Méthode appelée par le client
public async Task SendMessage(string user, string message)
{
// Envoie le message à TOUS les clients connectés
// "ReceiveMessage" est le nom de la méthode qui sera appelée côté JavaScript
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
Ciblage des Clients
L’objet Clients permet de choisir qui reçoit le message :
Clients.All: Tout le monde.Clients.Caller: Uniquement celui qui a envoyé la requête (réponse directe).Clients.Others: Tout le monde sauf l’envoyeur.Clients.User(userId): Un utilisateur spécifique (nécessite l’authentification).Clients.Group("MyGroup"): Un groupe d’utilisateurs.
Configuration
Dans Program.cs, il faut ajouter le service et mapper la route du Hub.
var builder = WebApplication.CreateBuilder(args);
// 1. Ajouter les services SignalR
builder.Services.AddSignalR();
var app = builder.Build();
// ... autres middlewares ...
app.MapControllers();
// 2. Mapper le Hub sur une URL spécifique
app.MapHub<ChatHub>("/chatHub");
app.Run();
Envoyer depuis un Contrôleur (IHubContext)
Le Hub gère les connexions, mais parfois on veut envoyer un message suite à une action externe (ex: fin d’un traitement background, appel API REST).
On ne peut pas instancier le Hub nous-mêmes (new ChatHub() ne marchera pas). On doit injecter IHubContext<T>.
[ApiController]
[Route("api/[controller]")]
public class NotificationController : ControllerBase
{
// On injecte le contexte du Hub
private readonly IHubContext<ChatHub> _hubContext;
public NotificationController(IHubContext<ChatHub> hubContext)
{
_hubContext = hubContext;
}
[HttpPost]
public async Task<IActionResult> NotifyUsers(string text)
{
// Envoi à tous les clients depuis le contrôleur
await _hubContext.Clients.All.SendAsync("ReceiveNotification", text);
return Ok();
}
}
Côté Client
Pour se connecter depuis une page web ou une autre application, on utilise une bibliothèque client.
En JavaScript : @microsoft/signalr.
// Création de la connexion
const connection = new signalR.HubConnectionBuilder()
.withUrl("/chatHub") // L'URL définie dans Program.cs
.build();
// Écoute des messages venant du serveur
connection.on("ReceiveMessage", (user, message) => {
console.log(`${user} dit : ${message}`);
// Mettre à jour l'UI ici
});
// Démarrage de la connexion
connection.start()
.then(() => console.log("Connecté à SignalR"))
.catch(err => console.error(err));
// Envoi d'un message vers le serveur
function sendMessage() {
const user = "Alice";
const message = "Salut tout le monde !";
// Appelle la méthode "SendMessage" du Hub C#
connection.invoke("SendMessage", user, message)
.catch(err => console.error(err));
}