Mise en place d’Azure SignalR avec ASP.NET Core

blog ai3 téléchargement-1 Mise en place d'Azure SignalR avec ASP.NET Core

Qu’est-ce que c’est ?

SignalR

Lors de la communication entre un client et un serveur, c’est la plupart du temps le client qui engage cette communication et le serveur qui y répond.

Cependant, il peut arriver que le serveur ait besoin d’engager la conversation. Ce sera par exemple nécessaire pour gérer les notifications, pour gérer la messagerie instantanée ou encore l’actualisation en direct des données que l’on regarde.

Il existe plusieurs moyens de faire ceci (WebSocket, Long Polling…). SignalR est une technologie de Microsoft permettant d’abstraire ça et d’utiliser la meilleure technologie disponible pour le navigateur du client.

Azure SignalR Service

Plutôt que d’avoir un endpoint local, l’idée est d’avoir un service azure auquel n’importe qui (un service, un webjob…) peut envoyer un message à destination d’un client qui y serait connecté.

La mise en place

Côté Azure

Commençons par ajouter une ressource de type « SignalR Service ».

blog ai3 image-15 Mise en place d'Azure SignalR avec ASP.NET Core

On lui donne ensuite un nom, un ResourceGroup, un emplacement géographique, on choisit si on le veut gratuit (mais avec un nombre de connexions et de messages limité) ou payant, et on crée notre service.

Ensuite, dans l’onglet « Keys », on trouvera les clés, host name et ConnectionStrings nécessaires pour se connecter à notre service.

Côté service externe

J’appelle « service externe » tout service ou application, en dehors du front ASP.NET Core principal, qui souhaite pouvoir envoyer des messages aux clients.

C’est là que la version service Azure de SignalR prend tout son intérêt. En effet, le service expose une API Rest que l’on va utiliser.

L’API se trouve sur cette URL :
https://{nom-du-service}.service.signalr.net:5002/api/v1/
Et sa documentation se trouve ici :
https://github.com/Azure/azure-signalr/blob/dev/docs/rest-api.md

Authentification

Avoir l’URL de l’API ne donne rien si l’on n’a pas l’autorisation de l’utiliser. On va donc s’authentifier avec un token JWT.

Vous aurez probablement besoin du package nuget System.IdentityModel.Tokens.Jwt pour que ça fonctionne. Personnellement, j’utilise la version 5.2.4. Pour utiliser l’API, j’utilise j’appelle cette méthode avec les paramètres suivants :

L’accessKey correspond à la clé indiquée dans l’onglet « Keys » de Azure. L’audienceUrl, en revanche, est variable : elle correspond à l’URL appelée.

Envoi d’un message à un utilisateur

Pour cela, il faut 4 choses :

  • Le nom du hub (qu’on définira dans la troisième partie : ASP.NET Core)
  • L’identifiant de l’utilisateur (qui pourra être un GUID, un email, un login…)
  • Un type d’événement (une simple chaîne de caractères – ex : « notification »)
  • Éventuellement un tableau d’objets qui sera ensuite sérialisé en JSON et transmis (ex : [« Nouveau message »])

L’URL complète sera donc :
https://{nom-du-service}.service.signalr.net:5002/api/v1/hubs/{nom-du-hub}/users/{identifiant-utilisateur}.
Ensuite, on peut générer le token (puisque celui-ci dépend de l’URL).

Étape suivante : générer le corps de la requête. Ce sera un objet JSON avec 2 propriétés : target et arguments. target correspond au type du message et arguments correspond aux informations supplémentaires que vous souhaiteriez transmettre.

Une fois que tout est prêt, on fait donc une requête POST vers l’URL déterminée précédemment, avec le body que l’on vient de définir, et avec ces headers :

On lance la requête et le message est transmis (si le destinataire existe et est connecté).

Côté application ASP.NET Core

Les packages NuGet

Il est nécessaire d’ajouter 2 packages NuGet, l’un pour gérer SignalR, l’autre pour la gestion du service Azure :

  • Microsoft.AspNetCore.SignalR (version 1.0.4)
  • Microsoft.Azure.SignalR (version 1.0.3)

Le Hub

Il s’agit du point central par lequel passent tous les messages. Il va falloir créer une classe héritant de la classe abstraite Microsoft.AspNetCore.SignalR.Hub.

Et que doit-on implémenter / surcharger dans notre classe ? Uniquement des comportements spécifiques. Autrement dit, pour un comportement de base, notre hub est vide. Si l’on veut des comportements particuliers lors de la connexion ou déconnexion d’un utilisateur, on peut surcharger les méthodes OnConnectedAsync() et OnDisconnectedAsync(). Il est également possible d’utiliser un attribut [Authorize] sur la classe pour n’accepter que les utilisateurs connectés à l’application.

Envoyer un message depuis l’application ASP.NET Core

Pour ça, il faut d’abord obtenir (via l’injection de dépendances) l’objet IHubContext<TypeDuHub>. On accède ensuite à la propriété Clients, puis on filtre sur les destinataires du message (ou on ne filtre pas du tout grâce à la propriété All), puis on appelle SendAsync en indiquant le nom de l’événement et éventuellement des données.

Définir l’identifiant de l’utilisateur

J’ai parlé plusieurs fois de l’identifiant de l’utilisateur. On est donc en droit de se demander comment celui-ci est choisi. L’idée est simple : implémenter l’interface IUserIdProvider. Voici donc un exemple simple se basant sur les claims de l’utilisateur connecté.

Initialiser SignalR

Il ne nous reste donc plus qu’à initialiser SignalR. On va donc faire ceci dans le fichier Startup.cs.

Côté JavaScript

Package NPM

Il faut commencer par installer les scripts (par exemple via npm) : @aspnet/signalr (j’utilise la version 1.0.4).

Ce package donne accès aux quelques fonctions JavaScript dont vous aurez besoin.

Connexion au hub

Ensuite, on démarre la connexion.

Envoi d’un message depuis JavaScript

Envoyons, depuis le client JavaScript, un message de type « notification » via SignalR à l’utilisateur de notre choix.

Abonnement aux messages SignalR

Dernière ligne droite. On a vu comment configurer SignalR côté client et côté serveur. On a vu comment envoyer un message depuis la solution ASP.NET Core, depuis un service externe et depuis JavaScript. Il ne reste plus qu’à réagir à la réception d’un tel message.

Conclusion

En très peu de ligne de code, on peut ainsi faire réagir notre client JavaScript à un événement asynchrone, provenant du site ou même d’un service externe.

Microsoft nous propose une solution compatible avec tous les navigateurs (même ceux qui ne sont pas compatibles avec WebSocket), simple à mettre en place et efficace.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.