Avril 2018

Volume 33, numéro 4

Cet article a fait l'objet d'une traduction automatique.

Cutting Edge - Présentation de ASP.NET Core SignalR

Par Dino Esposito | Avril 2018

Dino EspositoASP.NET SignalR est apparu il y a quelques années comme un outil permettant aux développeurs ASP.NET d’ajouter des fonctionnalités de temps réel aux applications. Tout scénario dans lequel une application ASP.NET a à recevoir des mises à jour fréquentes et asynchrones à partir du serveur, de surveiller les systèmes pour les jeux, ont été bonne cas d’usage pour la bibliothèque. Au fil des années, j’ai utilisé également actualiser l’interface utilisateur dans les scénarios d’architecture CQRS et d’implémenter un système de notification de Facebook similaire dans les applications socialware. À partir d’un point de vue plus technique, SignalR est une couche d’abstraction construite sur certains des mécanismes de transport qui peuvent établir une connexion en temps réel entre un client totalement compatible et le serveur. Le client est souvent un navigateur Web et le serveur est souvent un serveur Web, mais les deux ne sont pas limités à qui.

ASP.NET SignalR fait partie d’ASP.NET Core 2.1. Le modèle de programmation général de la bibliothèque est semblable à celle des ASP.NET classique, mais la bibliothèque elle-même a effectivement été entièrement réécrit. Toujours, les développeurs doivent devenir à l’aise avec le nouveau schéma, une fois qu’elles s’adaptent aux modifications qui existent ici et là. Dans cet article, j’explique comment utiliser la nouvelle bibliothèque dans une application Web canonique pour surveiller une tâche à distance et probablement prolongée.

Programme d’installation de l’environnement

Vous devrez peut-être deux packages NuGet pour utiliser la bibliothèque : Microsoft.AspNetCore.SignalR et Microsoft.AspNetCore.SignalR.Client. La première fournit les fonctionnalités principales ; le package de ce dernier est le client .NET et est nécessaire uniquement si vous créez une application Client .NET. Dans ce cas, nous utilisons il via un client Web, pour un package SignalR NPM serait nécessaire à la place. Je vais expliquer les détails de ce plus loin dans l’article. Notez que l’utilisation de SignalR dans le contexte d’une application Web basée sur le modèle d’application MVC n’est pas obligatoire. Vous pouvez utiliser les services de la bibliothèque SignalR directement à partir d’une application de console ASP.NET Core et pouvez également héberger la partie serveur du SignalR dans une application console.

Logiquement, la classe de démarrage de l’application doit contenir du code spécifique. En particulier, vous allez ajouter le service SignalR à la collection de services système et configurez-le pour une utilisation réelle. Figure 1 présente l’état par défaut d’une classe de démarrage qui utilise SignalR.

Figure 1 la classe de démarrage d’une Application de base d’ASP.NET SignalR

public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
    services.AddMvc();
    services.AddSignalR();
  }
  public void Configure(IApplicationBuilder app)
  {
    app.UseStaticFiles();
    app.UseDeveloperExceptionPage();
    // SignalR
    app.UseSignalR(routes =>
    {
      routes.MapHub<UpdaterHub>("/updaterDemo");
      routes.MapHub<ProgressHub>("/progressDemo");
    });
    app.UseMvcWithDefaultRoute();
  }
}

La configuration du service SignalR implique dans la définition d’un ou plusieurs itinéraires de serveur lier à un ou plusieurs points de terminaison dans un environnement côté serveur. La méthode MapHub < T >, les noms spécifiés, qui doit faire partie d’une URL de la demande, est liée à une instance d’une classe de concentrateur. La classe de concentrateur est battements du coeur de l’implémentation du protocole SignalR elle où les appels du client sont gérées. Vous créez un concentrateur pour chaque groupe logique de côté serveur prévoit d’accepter et traiter des appels. Une conversation SignalR est constituée de messages échangés entre les deux parties et chaque tiers peuvent appeler des méthodes sur l’autre partie réception aucune réponse, une ou plusieurs réponses ou simplement la notification d’une erreur. Toute implémentation de serveur ASP.NET Core SignalR expose un ou plusieurs des concentrateurs. Dans Figure 1, vous avez deux classes de hub : UpdaterHub et ProgressHub, lié à des chaînes uniques qui seront utilisés de façon interne pour composer l’URL cible des appels réels.

La classe de concentrateur

La classe de concentrateur dans une application SignalR est une classe ordinaire, simple qui hérite de la classe de base de concentrateur. La classe de base est le seul but de l’enregistrement aux développeurs d’écrire à nouveau le même code réutilisable. La classe de base fournit uniquement une infrastructure mais aucun comportement prédéfini. En particulier, il définit les membres dans Figure 2.

Classe de Base des membres de la figure 2 du concentrateur.

Membre Description
Clients Propriété qui expose la liste actuelle des clients gérés par le concentrateur.
Contexte Propriété qui expose le contexte actuel de l’appelant, y compris des informations telles que l’ID de la connexion et les revendications de l’utilisateur, s’il est disponible.
Groupes Propriété qui expose les différents sous-ensembles de clients qui peuvent avoir été définies par programme en tant que groupes au sein de la liste complète des clients. Un groupe est généralement créé comme un moyen de diffuser des messages spécifiques à un public sélectionné.
OnConnectedAsync Méthode virtuelle appelée chaque fois qu’un nouveau client se connecte au concentrateur.
OnDisconnectedAsync Méthode virtuelle appelée chaque fois qu’un nouveau client se déconnecte au concentrateur.

La classe la plus simple de concentrateur est très simple comme suit :

public class ProgressHub : Hub
{
}

Il est intéressant, qui est simplement le formulaire du concentrateur si vous l’utilisez dans une méthode de contrôleur dans le contexte d’une application ASP.NET MVC de base. Presque tous les exemples, que vous souhaiterez peut-être sur ASP.NET Core SignalR (y compris l’exemple de conversation) ont tendance à afficher un direct et une liaison bidirectionnelle entre le client et le concentrateur sans aucune sorte d’intermédiaires par un contrôleur. Dans ce cas, le concentrateur prendra la forme légèrement plus mis en forme :

public class SampleChat : Hub
{     
  // Invoked from outside the hub
  public void Say(string message)
  {
    // Invoke method on listening client(s)
    return Clients.All.InvokeAsync("Said", message);
  }
}

Contrairement à l’exemple SignalR conversation canonique qui est rehashed des dizaines de billets de blog, l’exemple, je présenterai ici ne définit pas réellement d’une conversation bidirectionnelle entre client et serveur. La connexion est établie à partir du client, mais après que le client n’envoie pas de toutes les autres demandes. Le serveur, au lieu de cela, être surveillance de la progression d’une tâche et envoi de données au client lorsqu’il est approprié. En d’autres termes, la classe de concentrateur doit avoir des méthodes publiques en tant que le code précédent uniquement si le cas d’usage requiert que le client appelle directement dans les. Si elle semble un peu obscur, l’exemple suivant sera suffisamment éclairer.

Analyse d’une tâche à distance

Voici le scénario : Une application ASP.NET Core présente une interface HTML pour l’utilisateur déclencher une tâche à distance (par exemple, la création d’un rapport) qui peut être longue à l’utilisateur. Pour cette raison, en tant que développeur que vous souhaitez afficher une barre de progression pour fournir des commentaires en continu (consultez Figure 3).

À l’aide de SignalR pour surveiller la progression d’une tâche à distance
Figure 3 à l’aide de SignalR pour surveiller la progression d’une tâche à distance

Comme vous pouvez deviner, dans cet exemple montre comment le client et le serveur configurez une conversation SignalR actifs dans le contexte d’un projet ASP.NET Core. À ce stade du développement, vous avez un projet MVC entièrement fonctionnels simplement étendu avec le code de démarrage de Figure 1. Nous allons définir l’infrastructure client. Vous devez disposer de ce travail dans chaque Razor (ou le HTML brut) le programme d’installation vue qui interagit avec un point de terminaison SignalR.

Pour communiquer avec un point de terminaison SignalR à partir d’un navigateur Web, la première chose à que faire est d’ajouter une référence à la bibliothèque cliente SignalR JavaScript :

<script src="~/scripts/signalr.min.js">
</script>

Vous pouvez obtenir ce fichier JavaScript dans un nombre de façons. Est la plus recommandée via l’outil Gestionnaire de Package Node.js (NPM) qui est disponible sur pratiquement n’importe quel ordinateur de développement, en particulier après Visual Studio 2017. Via NPM, vous recherchez le client ASP.NET Core SignalR nommé @aspnet/signalr et l’installer. Il copie un ensemble de fichiers de JavaScript sur votre disque, seul d'entre eux est strictement nécessaire dans la plupart des scénarios. Malgré tout, il est très simple de liaison d’un fichier JavaScript, et vous pouvez obtenir ce fichier de nombreuses manières, y compris les copiant à partir d’un projet ASP.NET Core SignalR antérieur. Toutefois, NPM est la seule façon de que l’équipe fournit pour obtenir le script. Notez également que ASP.NET Core SignalR ne dépend plus jQuery.

Dans l’application cliente, vous devez également un autre, plus spécifique, segment de code JavaScript. En particulier, vous avez besoin de code similaire à celui-ci :

var progressConnection =
  new signalR.HubConnection("/progressDemo");
progressConnection.start();

Vous créez une connexion au concentrateur SignalR qui correspond au chemin d’accès spécifié. Plus précisément, le nom que vous passez en tant qu’argument à HubConnection doit être un des noms que vous avez mappé à un itinéraire dans la classe de démarrage. En interne, l’objet HubConnection prépare une chaîne d’URL qui résulte de la concaténation de l’URL du serveur et le nom donné. Cette URL est traitée uniquement si elle correspond à l’un des itinéraires configurés. Notez également que si le client et le serveur ne sont pas la même application Web, puis HubConnection doit être passée l’URL complète de l’application ASP.NET Core qui héberge le concentrateur SignalR, ainsi que le nom du concentrateur.

L’objet de connexion de hub JavaScript doit ensuite être ouverts via la méthode de démarrage. Vous pouvez utiliser les promesses de JavaScript, en particulier la méthode puis — ou asynchrones / d’attente dans TypeScript pour effectuer les actions suivantes telles que l’initialisation d’une interface utilisateur. Une connexion SignalR est identifiée par un ID de chaîne.

Il est important de noter que ASP.NET Core SignalR ne prend plus en charge automatique vous reconnecter si la connexion de transport ou le serveur échoue. Dans les versions antérieures, en cas de défaillance du serveur, le client tente de rétablir une connexion selon un algorithme de planification et, en cas de réussite, elle s’ouvre une connexion avec le même ID. Dans SignalR Core si la connexion supprime le client peut uniquement redémarrez-le via le début de la méthode et il en résulte dans une instance de l’autre connexion sur un ID de connexion différents.

L’API de rappel de Client

Un autre segment fondamental de code JavaScript est le code JavaScript qui sera rappelé par le concentrateur actualiser l’interface et la prise en compte sur le client une progression réalisée sur le serveur. La façon dont vous écrivez ce code est un peu différente dans ASP.NET Core SignalR à partir de quel qu’il était dans les versions antérieures, mais l’intention est exactement le même. Dans notre exemple, nous avons trois méthodes qui peut être appelées de nouveau à partir du serveur : initProgressBar, updateProgressBar et clearProgressBar. Bien entendu, les noms et les signatures sont arbitraires. Voici un exemple d'implémentation :

progressConnection.on("initProgressBar", () => {
  setProgress(0);
  $("#notification").show();
});
progressConnection.on("updateProgressBar", (perc) => {
  setProgress(perc);
});
progressConnection.on("clearProgressBar", () => {
  setProgress(100);
  $("#notification").hide();
});

Par exemple, lorsque la méthode initProgressBar est rappelée à partir du serveur le setProgress d’assistance fonction JavaScript configurer la barre de progression (la démonstration utilise un composant de barre de progression d’amorçage) et l’afficher. Notez que la bibliothèque jQuery est utilisée dans le code, mais uniquement pour mettre à jour l’interface utilisateur. Comme indiqué, le client SignalR Core library n’est plus un plug-in jQuery. Autrement dit, si votre interface utilisateur est basé sur, par exemple, angulaire, puis vous peut-être pas à utiliser jQuery à tout.

Événements côté serveur

L’élément manquant est la partie de la solution qui décide quand il est sur le temps d’appeler une fonction de client. Il existe deux principaux scénarios. Un est lorsque le client appelle une action de serveur via une API Web ou d’un point de terminaison du contrôleur. L’autre est lorsque le client appelle directement le concentrateur. Au final, tout est question où de code de la tâche qui rappelle le client.

Dans l’exemple canonique de conversation, tout s’effectue dans le concentrateur : performances de n’importe quel requis logique et l’envoi de messages à la connexion appropriée. Analyse d’une tâche à distance est une chose différente. Elle suppose un processus d’entreprise en cours d’exécution en arrière-plan qui signale la progression d’une certaine façon. Techniquement, vous pouvez avoir ce processus codé dans le hub et la configurer à partir de là, une conversation avec l’interface utilisateur du client. Ou vous pouvez le processus qui a déclenché par un contrôleur (API) et utiliser le hub uniquement comme un moyen de transmettre des événements au client. Même avec plus de réalisme qu’indiqué dans l’exemple, vous avez le processus codé dans une couche sous le niveau de contrôleurs.

En bref, vous définissez la classe de concentrateur et rendre disponible partout où vous pouvez décider quand et s’il convient d’appeler des fonctions de client. La chose intéressante est ce qui est nécessaire pour injecter l’instance de concentrateur dans un contrôleur ou une autre classe d’entreprise. La démonstration injecte le concentrateur dans un contrôleur, mais il serait n’exactement la même pour une autre classe de niveau inférieur. L’exemple TaskController est appelé via JavaScript directement depuis le client pour déclencher la tâche à distance dont progresse se déplace alors vers la barre de progression :

public class TaskController : Controller
{
  private readonly IHubContext<ProgressHub> _progressHubContext;
  public TaskController(IHubContext<ProgressHub> progressHubContext)
  {
    _progressHubContext = progressHubContext;
  }
  public IActionResult Lengthy()
  {
    // Perform the task and call back
  }
}

Vous injectez un concentrateur dans un contrôleur ou dans toute autre classe via l’interface IHubContext < THub >. L’interface IHubContext encapsule l’instance de concentrateur, mais ne vous donne un accès direct à celle-ci. À partir de là, vous pouvez distribuer les messages vers l’interface utilisateur, mais vous ne peut pas accéder, par exemple, l’ID de connexion. Supposons que la tâche à distance est effectuée dans la méthode longue et il s’agit d’il vous souhaitez mettre à jour de la barre de progression du client :

progressHubContext
  .Clients
  .Client(connId)
  .InvokeAsync("updateProgressBar", 45);

L’ID de connexion peut être extraites au sein de la classe de concentrateur, mais pas à partir d’un contexte du concentrateur générique comme dans cet exemple. Par conséquent, la façon la plus simple est pour la méthode du client passer la chaîne de connexion lorsqu’il démarre la tâche à distance :

public void Lengthy([Bind(Prefix="id")] string connId) { … }

Au final, la classe de contrôleur reçoit l’ID de connexion SignalR, est injectée le contexte du concentrateur et agit via le contexte d’appel de méthodes via une API typée non générique, la méthode InvokeAsync. Utilisé de cette façon, il est inutile d’avoir des méthodes dans la classe de concentrateur ! Si vous trouvez étonnants, bien, regardez le code à bit.ly/2DWd8SV.

Pour résumer

Cet article décrit à l’aide d’ASP.NET Core SignalR dans le contexte d’une application Web pour surveiller une tâche à distance. Le concentrateur est pratiquement vide que toute la logique de notification est intégrée dans ce contrôleur et orchestrée via le contexte du concentrateur injecté via DI. Il s’agit simplement le point de départ d’une visite de plus de ASP.NET Core SignalR. Ensuite, j’explorent l’infrastructure et Explorer concentrateurs typés, également.


Dino Espositoa créé la documentation plus de 20 et 1 000 articles de sa carrière de 25 ans. L’auteur de « Le plus Break, « afficher un style théâtrales, Esposito est occupé à écrire un logiciel pour un monde un en tant que la stratégie numérique à BaxEnergy. Suivre sur Twitter : @despos.

Grâce à l’expert Microsoft suivant pour consulter cet article : Andrew Stanton-Nurse


Discussion sur cet article sur le forum MSDN Magazine