Fonctionnement d’ASP.NET Core SignalR
Serveurs et classe Hub
La classe Hub
est un concept de serveur SignalR. Elle est définie dans l’espace de noms Microsoft.AspNetCore.SignalR
et fait partie du package NuGet Microsoft.AspNetCore.SignalR. Les applications web ASP.NET Core qui ciblent le kit de développement logiciel (SDK) Microsoft.NET.Sdk.Web n’ont pas besoin d’ajouter une référence de package pour SignalR, car elle est déjà disponible comme faisant partie de l’infrastructure partagée.
Un Hub
est exposé via un itinéraire. Par exemple, la route https://www.contoso-pizza.com/hubs/orders
pourrait être utilisée pour représenter une implémentation OrdersHub
. À travers les différentes API de hub, les auteurs peuvent définir des méthodes et des événements.
Il existe deux modalités pour exposer des méthodes sur un hub. Vous créez une sous-classe des types et des méthodes d’écriture qui suivent :
Exemple Hub
Prenons comme point de référence l’objet Notification
suivant :
namespace RealTime.Models;
public record Notification(string Text, DateTime Date);
L’objet peut être partagé en cas d’utilisation du kit SDK du client .NET pour permettre au serveur et au client d’avoir exactement le même objet. Imaginez un hub de notification :
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleServer.Hubs;
public sealed class NotificationHub : Hub
{
public Task NotifyAll(Notification notification) =>
Clients.All.SendAsync("NotificationReceived", notification);
}
Quant à la différence entre les méthodes et les événements, la méthode utilisée dans la précédente implémentation du hub est NotifyAll
, alors que l’événement est NotificationReceived
. NotificationHub
est une sous-classe de Hub
. La méthode NotifyAll
retourne Task
et accepte un seul paramètre Notification
. La méthode est exprimée sous la forme de l’appel de SendAsync
à partir de Clients.All
, qui représente tous les clients connectés. L’événement NotificationReceived
est déclenché, en fonction de l’instance notification
.
L’instance IHubContext
Vous déclenchez des événements à partir d’une instance de Hub
ou IHubContext
. Le hub SignalR est l’abstraction principale pour l’envoi de messages aux clients connectés au serveur SignalR. Vous pouvez également envoyer des messages à partir d’autres emplacements de votre application à l’aide de l’un des types suivants :
- IHubContext<THub> : contexte où
THub
représente un hub standard. - IHubContext<THub,T> : Contexte où
THub
représente un hub générique fortement typé, et oùT
représente le type de client correspondant.
Important
IHubContext
permet d’envoyer des notifications aux clients. Il n’est pas utilisé pour appeler des méthodes sur le Hub
.
Exemple : IHubContext
Compte tenu de la précédente implémentation du hub de notification, vous pouvez utiliser IHubContext<NotificationHub>
de la manière suivante :
using Microsoft.AspNetCore.SignalR;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleServer.Services;
public sealed class NotificationService(
IHubContext<NotificationHub> hubContext)
{
public Task SendNotificationAsync(Notification notification) =>
notification is not null
? hubContext.Clients.All.SendAsync("NotificationReceived", notification)
: Task.CompletedTask;
}
Le code C# précédent s’appuie sur IHubContext<NotificationHub>
pour accéder à la liste contextuelle des clients, ce qui permet de diffuser des notifications. Le paramètre de constructeur principal hubContext
qui est capturé dans l’étendue est utilisé pour déclencher l’événement "NotificationReceived"
, mais il n’est pas destiné à être utilisé pour appeler la méthode NotifyAll
du hub.
Méthodes
Les méthodes Hub
et Hub<T>
sont comme n’importe quelle autre méthode C#. Elles définissent un type de retour, un nom de méthode et des paramètres.
- Le type de retour le plus courant pour une méthode de hub est
Task
ouTask<TResult>
, ce qui représente le fonctionnement asynchrone du hub. - Le nom de la méthode est utilisé pour appeler la méthode à partir des clients. Vous pouvez le personnaliser à l’aide de HubMethodNameAttribute.
- Les paramètres sont facultatifs, mais quand ils sont définis, les clients sont censés fournir les arguments correspondants.
Les méthodes ne sont pas obligées de déclencher des événements, mais elles le font souvent.
Événements
Vous pouvez vous abonner à un événement par son nom à partir d’un client. Le serveur est responsable du déclenchement des événements. Les événements Hub
, Hub<T>
, IHubContext<THub>
et IHubContext<THub, T>
sont nommés et définissent jusqu’à 10 paramètres. Les événements sont déclenchés sur le serveur et gérés par les clients intéressés. Un client est considéré comme intéressé quand il s’abonne aux événements de la connexion de son hub. Les clients peuvent déclencher indirectement des événements quand ils appellent des méthodes de hub qui déclenchent des événements à la suite de leur appel. Toutefois, les événements ne peuvent pas être déclenchés directement par les clients, car il s’agit de la responsabilité du serveur.
Étendues des clients des événements
Vous appelez les événements à partir d’une instance de IClientProxy. Vous implémentez les interfaces IHubClients et IHubCallerClients à partir du type Clients. Il existe de nombreuses façons de définir l’étendue à une instance IClientProxy
spécifique. Vous pouvez cibler les étendues suivantes avec la propriété Hub.Clients
:
Membre | Détails |
---|---|
All |
Tous les clients connectés (par exemple une diffusion). |
AllExcept |
Tous les clients connectés, à l’exception des connexions spécifiées (par exemple la diffusion filtrée). |
Caller |
Client connecté qui a déclenché la méthode (par exemple un écho). |
Client |
La connexion cliente spécifiée (connexion unique). |
Clients |
Les connexions clientes spécifiées (connexions multiples). |
Group |
Tous les clients connectés dans le groupe spécifié. |
GroupExcept |
Tous les clients connectés dans le groupe spécifié, à l’exception des connexions spécifiées. |
Groups |
Tous les clients connectés au sein des groupes spécifiés (plusieurs groupes). |
Others |
Tous les clients connectés, à l’exception du client qui a déclenché la méthode. |
OthersInGroup |
Tous les clients connectés dans le groupe spécifié, à l’exception du client qui a déclenché la méthode. |
User |
Tous les clients connectés pour l’utilisateur spécifié (un seul utilisateur peut se connecter sur plusieurs appareils). |
Users |
Tous les clients connectés pour les utilisateurs spécifiés. |
Exemples d’étendues
Examinez les images suivantes, qui peuvent vous aider à visualiser la manière dont le hub envoie des messages aux clients ciblés. Vous pouvez agrandir les images pour améliorer la lisibilité.
Diffuser à tout le monde
Tous les clients connectés reçoivent ce message, quel que soit le groupe auquel ils appartiennent ou non.
Utilisateur isolé
Un seul utilisateur reçoit ce message, quel que soit le nombre d’appareils qu’il utilise.
Groupe isolé
Seuls les clients qui appartiennent à un certain groupe reçoivent ce message.
Clients et classe HubConnection
La classe HubConnection
est un concept de client SignalR, qui représente la connexion du client au serveur Hub
. Elle est définie dans l’espace de noms Microsoft.AspNetCore.SignalR.Client
et fait partie du package NuGet Microsoft.AspNetCore.SignalR.Client.
Vous créez un HubConnection
à l’aide du modèle de générateur et du type HubConnectionBuilder
correspondant. À partir de l’itinéraire du hub (ou System.Uri), vous pouvez créer un HubConnection
. Le générateur peut également spécifier des options de configuration supplémentaires, qui comprennent entre autres la journalisation, le protocole souhaité, le transfert de jetons d’authentification et la reconnexion automatique.
L’API HubConnection
expose les fonctions de démarrage et d’arrêt, utilisées pour démarrer et arrêter la connexion au serveur. De plus, il existe des fonctionnalités pour le streaming, l’appel de méthodes de hub et l’abonnement aux événements.
Exemple de création de HubConnection
Pour créer un objet HubConnection
à partir du kit SDK du client .NET SignalR, utilisez le type HubConnectionBuilder
:
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleClient;
public sealed class Consumer : IAsyncDisposable
{
private readonly string HostDomain =
Environment.GetEnvironmentVariable("HOST_DOMAIN");
private HubConnection _hubConnection;
public Consumer()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(new Uri($"{HostDomain}/hub/notifications"))
.WithAutomaticReconnect()
.Build();
}
public Task StartNotificationConnectionAsync() =>
_hubConnection.StartAsync();
public async ValueTask DisposeAsync()
{
if (_hubConnection is not null)
{
await _hubConnection.DisposeAsync();
_hubConnection = null;
}
}
}
Appeler les méthodes d’un hub
Si un client reçoit une instance cliente de HubConnection
a démarré correctement, ce client peut appeler des méthodes sur un hub à l’aide des extensions InvokeAsync ou SendAsync. Si la méthode du hub retourne Task<TResult>
, le résultat de InvokeAsync<TResult>
est de type TResult
. Si la méthode du hub retourne Task
, cela signifie qu’il n’existe aucun résultat. InvokeAsync
et SendAsync
exigent tous les deux le nom de la méthode du hub ainsi qu’un nombre de paramètres compris entre zéro et dix.
- InvokeAsync : appelle une méthode de hub sur le serveur à l’aide du nom de méthode spécifié et d’arguments facultatifs.
- SendAsync : appelle une méthode de hub sur le serveur à l’aide du nom de méthode spécifié et d’arguments facultatifs. Cette méthode n’attend pas de réponse du récepteur.
Exemple d’appel de méthode de hub
Quand SendNotificationAsync
ajoute une méthode à la classe Consumer
précédente, SendNotificationAsync
délègue à _hubConnection
et appelle la méthode NotifyAll
sur le hub du serveur en fonction de l’instance de Notification
.
public Task SendNotificationAsync(string text) =>
_hubConnection.InvokeAsync(
"NotifyAll", new Notification(text, DateTime.UtcNow));
Gérez les événements
Pour gérer les événements, vous devez inscrire un gestionnaire auprès de l’instance de HubConnection
. Appelez l’une des surcharges de HubConnectionExtensions.On quand vous connaissez le nom de la méthode de hub et avez un nombre de paramètres compris entre zéro et huit. Le gestionnaire peut répondre à l’une des variantes suivantes de Action
:
- Action
- Action<T>
- Action<T1,T2>
- Action<T1,T2,T3>
- Action<T1,T2,T3,T4>
- Action<T1,T2,T3,T4,T5>
- Action<T1,T2,T3,T4,T5,T6>
- Action<T1,T2,T3,T4,T5,T6,T7>
- Action<T1,T2,T3,T4,T5,T6,T7,T8>
Vous pouvez également utiliser les API de gestionnaire asynchrone, qui sont des Func<TResult>
où TResult
est une variante de Task
:
Func<Task>
Func<T,Task>
Func<T1,T2,Task>
Func<T1,T2,T3,Task>
Func<T1,T2,T3,T4,Task>
Func<T1,T2,T3,T4,T5,Task>
Func<T1,T2,T3,T4,T5,T6,Task>
Func<T1,T2,T3,T4,T5,T6,T7,Task>
Func<T1,T2,T3,T4,T5,T6,T7,T8,Task>
Le résultat de l’inscription d’un gestionnaire d’événements est un IDisposable
, qui sert d’abonnement. Pour désabonner le gestionnaire, appelez Dispose.
Exemple d’inscription à un événement
En mettant à jour la classe Consumer
précédente, vous vous inscrivez à un événement en fournissant un gestionnaire et en appelant On
:
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;
using RealTime.Models;
namespace ExampleClient;
public sealed class Consumer : IAsyncDisposable
{
private readonly string HostDomain =
Environment.GetEnvironmentVariable("HOST_DOMAIN");
private HubConnection _hubConnection;
public Consumer()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl(new Uri($"{HostDomain}/hub/notifications"))
.WithAutomaticReconnect()
.Build();
_hubConnection.On<Notification>(
"NotificationReceived", OnNotificationReceivedAsync);
}
private async Task OnNotificationReceivedAsync(Notification notification)
{
// Do something meaningful with the notification.
await Task.CompletedTask;
}
// Omitted for brevity.
}
La méthode OnNotificationReceivedAsync
est appelée quand l’instance de hub du serveur déclenche l’événement "NotificationReceived"
.
Mises à jour des commandes en temps réel de Contoso Pizza
Le code serveur de l’application web doit avoir une implémentation de Hub
et exposer une route aux clients. Le Hub
peut utiliser l’identificateur unique de l’objet de commande pour créer un groupe de suivi. Toutes les mises à jour des changements d’état des commandes peuvent ensuite être communiquées à ce groupe.
Le code client doit également être mis à jour pour indiquer que l’application Contoso Pizza est une application Blazor WebAssembly. Vous pouvez utiliser le kit SDK JavaScript ou celui du client .NET. Remplacez ensuite la fonctionnalité d’interrogation côté client par du code qui génère un HubConnection
, puis démarrez la connexion au serveur. Quand l’utilisateur accède à la page de suivi des commandes, le code doit joindre le groupe spécifique de la commande où les mises à jour des changements sont envoyées. Vous devez vous abonner à l’événement pour connaître les changements d’état de la commande, puis gérer la situation de manière appropriée.