Tutoriel : Publication de messages et abonnement entre clients WebSocket avec le sous-protocole
Dans le tutoriel Création d’une application de conversation, vous avez appris à utiliser les API WebSocket pour envoyer et recevoir des données avec Azure Web PubSub. Comme vous pouvez le constater, aucun protocole n’est nécessaire lorsque le client communique avec le service. Par exemple, vous pouvez envoyer n’importe quel type de données à l’aide de WebSocket.send()
, et le serveur le reçoit tout comme il l’est. Le processus d’API WebSocket est facile à utiliser, mais la fonctionnalité est limitée. Par exemple, vous ne pouvez pas spécifier le nom de l’événement que vous envoyez au serveur, ni publier un message sur d’autres clients au lieu de l’envoyer au serveur. Dans ce tutoriel, vous découvrez comment utiliser le sous-protocole pour étendre les fonctionnalités du client.
Dans ce tutoriel, vous allez apprendre à :
- Créer une instance de service Azure Web PubSub
- Générer l’URL complète pour établir la connexion WebSocket
- Publier des messages entre des clients WebSocket avec le sous-protocole
Si vous n’avez pas d’abonnement Azure, créez un compte gratuit Azure avant de commencer.
Prérequis
Utilisez l’environnement Bash dans Azure Cloud Shell. Pour plus d’informations, consultez Démarrage rapide pour Bash dans Azure Cloud Shell.
Si vous préférez exécuter les commandes de référence de l’interface de ligne de commande localement, installez l’interface Azure CLI. Si vous exécutez sur Windows ou macOS, envisagez d’exécuter Azure CLI dans un conteneur Docker. Pour plus d’informations, consultez Guide pratique pour exécuter Azure CLI dans un conteneur Docker.
Si vous utilisez une installation locale, connectez-vous à Azure CLI à l’aide de la commande az login. Pour finir le processus d’authentification, suivez les étapes affichées dans votre terminal. Pour connaître les autres options de connexion, consultez Se connecter avec Azure CLI.
Lorsque vous y êtes invité, installez l’extension Azure CLI lors de la première utilisation. Pour plus d’informations sur les extensions, consultez Utiliser des extensions avec Azure CLI.
Exécutez az version pour rechercher la version et les bibliothèques dépendantes installées. Pour effectuer une mise à niveau vers la dernière version, exécutez az upgrade.
- La version 2.22.0 (ou une version ultérieure) d’Azure CLI est requise pour cette configuration. Si vous utilisez Azure Cloud Shell, la version la plus récente est déjà installée.
Important
Des chaînes de connexion brutes sont utilisées dans cet article à des fins de démonstration uniquement.
Une chaîne de connexion contient les informations d’autorisation requises pour que votre application accède au service Azure Web PubSub. La clé d’accès à l’intérieur dans la chaîne de connexion est semblable à un mot de passe racine pour votre service. Dans les environnements de production, protégez toujours vos clés d’accès. Utilisez Azure Key Vault pour gérer et faire pivoter vos clés en toute sécurité, et sécurisez votre connexion avec WebPubSubServiceClient
.
Évitez de distribuer des clés d’accès à d’autres utilisateurs, de les coder en dur ou de les enregistrer en texte brut dans un emplacement accessible à d’autres personnes. Effectuez une rotation de vos clés si vous pensez qu’elles ont pu être compromises.
Création d’une instance Azure Web PubSub
Créer un groupe de ressources
Un groupe de ressources est un conteneur logique dans lequel les ressources Azure sont déployées et gérées. Utilisez la commande az group create pour créer un groupe de ressources nommé myResourceGroup
à l’emplacement eastus
.
az group create --name myResourceGroup --location EastUS
Créer une instance Web PubSub
Exécutez la commande az extension add pour installer ou mettre à niveau l’extension webpubsub vers la version actuelle.
az extension add --upgrade --name webpubsub
Utilisez la commande az webpubsub create d’Azure CLI pour créer une instance Web PubSub dans le groupe de ressources que vous avez créé. La commande suivante crée une ressource Web PubSub GRATUITE sous le groupe de ressources myResourceGroup dans la zone EastUS :
Important
Chaque ressource Web PubSub doit avoir un nom unique. Remplacez <your-unique-keyvault-name> par le nom de votre Web PubSub dans les exemples suivants.
az webpubsub create --name "<your-unique-resource-name>" --resource-group "myResourceGroup" --location "EastUS" --sku Free_F1
La sortie de cette commande affiche les propriétés de la ressource que vous venez de créer. Notez les deux propriétés ci-dessous :
- Nom de la ressource : nom que vous avez fourni au paramètre
--name
ci-dessus. - Nom d’hôte : dans l’exemple, le nom d’hôte est
<your-unique-resource-name>.webpubsub.azure.com/
.
À ce stade, votre compte Azure est le seul autorisé à effectuer des opérations sur cette nouvelle ressource.
Récupération de la chaîne de connexion pour une utilisation ultérieure
Des chaînes de connexion brutes sont utilisées dans cet article à des fins de démonstration uniquement. Dans les environnements de production, protégez toujours vos clés d’accès. Utilisez Azure Key Vault pour gérer et faire pivoter vos clés en toute sécurité, et sécurisez votre connexion avec WebPubSubServiceClient
.
Utilisez la commande Azure CLI az webpubsub key pour obtenir la valeur ConnectionString du service. Remplacez l’espace réservé <your-unique-resource-name>
par le nom de votre instance Azure Web PubSub.
az webpubsub key show --resource-group myResourceGroup --name <your-unique-resource-name> --query primaryConnectionString --output tsv
Copiez la chaîne de connexion à utiliser plus tard.
Copiez la chaîne ConnectionString extraite et utilisez-la plus loin comme valeur de <connection_string>
dans la suite de ce tutoriel.
Configuration du projet
Prérequis
Utilisation d’un sous-protocole
Le client peut lancer une connexion WebSocket avec un sous-protocole spécifique. Le service Azure Web PubSub prend en charge un sous-protocole appelé json.webpubsub.azure.v1
, qui permet aux clients de publier/s’abonner directement via le service Web PubSub plutôt que d’avoir à effectuer un aller-retour au serveur en amont. Pour plus d’informations sur ce sous-protocole, consultez Sous-protocole JSON WebSocket pris en charge par Azure Web PubSub.
Tout autre nom de protocole utilisé est ignoré par le service et transmis au serveur dans le gestionnaire d’événements de connexion. Vous pouvez ainsi créer vos propres protocoles.
Créons maintenant une application web avec le sous-protocole json.webpubsub.azure.v1
.
Installer des dépendances
mkdir logstream cd logstream dotnet new web dotnet add package Microsoft.Extensions.Azure dotnet add package Azure.Messaging.WebPubSub
Créez le côté serveur pour héberger l’API et la page web
/negotiate
.Mettez à jour
Program.cs
avec le code suivant.- Utilisez
AddAzureClients
pour ajouter le service client et lire la chaîne de connexion à partir de la configuration. - Ajoutez
app.UseStaticFiles();
avantapp.Run();
pour prendre en charge les fichiers statiques. - Enfin, mettez à jour
app.MapGet
pour générer le jeton d’accès client avec des demandes/negotiate
.
using Azure.Messaging.WebPubSub; using Microsoft.Extensions.Azure; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAzureClients(s => { s.AddWebPubSubServiceClient(builder.Configuration["Azure:WebPubSub:ConnectionString"], "stream"); }); var app = builder.Build(); app.UseStaticFiles(); app.MapGet("/negotiate", async context => { var service = context.RequestServices.GetRequiredService<WebPubSubServiceClient>(); var response = new { url = service.GetClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" }).AbsoluteUri }; await context.Response.WriteAsJsonAsync(response); }); app.Run();
- Utilisez
Créez la page web.
Créez une page HTML comportant le contenu suivant et enregistrez-la sous
wwwroot/index.html
:<html> <body> <div id="output"></div> <script> (async function () { let res = await fetch('/negotiate') let data = await res.json(); let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1'); ws.onopen = () => { console.log('connected'); }; let output = document.querySelector('#output'); ws.onmessage = event => { let d = document.createElement('p'); d.innerText = event.data; output.appendChild(d); }; })(); </script> </body> </html>
Le code ci-dessus se connecte au service et imprime tous les messages reçus sur la page. La principale modification est que le sous-protocole est spécifié lors de la création de la connexion WebSocket.
Exécutez le serveur.
Nous utilisons l’outil Secret Manager pour .NET Core afin de définir la chaîne de connexion. Exécutez la commande suivante, en remplaçant
<connection_string>
par la chaîne récupérée à l’étape précédente, et ouvrez http://localhost:5000/index.html dans un navigateur :dotnet user-secrets init dotnet user-secrets set Azure:WebPubSub:ConnectionString "<connection-string>" dotnet run
Si vous utilisez Chrome, vous pouvez appuyer sur F12 ou faire un clic droit sur ->Inspecter ->Outils de développement, puis sélectionner l’onglet Réseau. Chargez la page web et vous pouvez voir que la connexion WebSocket est établie. Sélectionnez pour inspecter la connexion WebSocket. Le message d’événement
connected
est reçu dans le client (cf. ci-dessous). Vous pouvez obtenir leconnectionId
généré pour ce client.{"type":"system","event":"connected","userId":null,"connectionId":"<the_connection_id>"}
Avec l’aide du sous-protocole, vous pouvez donc obtenir certaines métadonnées de la connexion lorsqu’elle est connected
.
Le client reçoit désormais un message JSON au lieu d’un texte brut. Le message JSON contient plus d’informations telles que le type et la source du message. Vous pouvez utiliser ces informations pour effectuer un traitement plus poussé du message (par l’exemple l’afficher dans un autre style s’il provient d’une source différente), que vous trouverez dans les sections suivantes.
Publication de messages provenant du client
Dans le tutoriel Créer une application de conversation, lorsque le client envoie un message via une connexion WebSocket au service Web PubSub, le service déclenche un événement utilisateur côté serveur. Avec le sous-protocole, le client dispose de davantage de fonctionnalités en envoyant un message JSON. Par exemple, vous pouvez publier des messages directement à partir du client via le service Web PubSub sur d’autres clients.
Cette fonctionnalité est utile pour diffuser en temps réel une grande quantité de données vers d’autres clients. Utilisons-la pour créer une application de streaming de journaux, qui peut transmettre en temps réel les journaux de la console au navigateur.
Création du programme de streaming
Créez un programme
stream
:mkdir stream cd stream dotnet new console
Mettez à jour
Program.cs
avec le contenu suivant :using System; using System.Net.Http; using System.Net.WebSockets; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace stream { class Program { private static readonly HttpClient http = new HttpClient(); static async Task Main(string[] args) { // Get client url from remote var stream = await http.GetStreamAsync("http://localhost:5000/negotiate"); var url = (await JsonSerializer.DeserializeAsync<ClientToken>(stream)).url; var client = new ClientWebSocket(); client.Options.AddSubProtocol("json.webpubsub.azure.v1"); await client.ConnectAsync(new Uri(url), default); Console.WriteLine("Connected."); var streaming = Console.ReadLine(); while (streaming != null) { if (!string.IsNullOrEmpty(streaming)) { var message = JsonSerializer.Serialize(new { type = "sendToGroup", group = "stream", data = streaming + Environment.NewLine, }); Console.WriteLine("Sending " + message); await client.SendAsync(Encoding.UTF8.GetBytes(message), WebSocketMessageType.Text, true, default); } streaming = Console.ReadLine(); } await client.CloseAsync(WebSocketCloseStatus.NormalClosure, null, default); } private sealed class ClientToken { public string url { get; set; } } } }
Nous rencontrons ici un nouveau concept : celui de « groupe ». Ce concept logique permet, dans un hub, de publier un message sur un groupe de connexions. Un hub peut comporter plusieurs groupes, et un client a la possibilité de s’abonner à plusieurs groupes en même temps. Lorsque vous utilisez le sous-protocole, vous pouvez publier un message sur un groupe seulement au lieu de le diffuser sur l’ensemble du hub. Pour plus d’informations sur les termes, consultez les concepts de base.
Dans la mesure où nous utilisons un groupe, nous devons également mettre à jour la page web
index.html
pour joindre le groupe lorsque la connexion WebSocket est établie dans le rappelws.onopen
.let ackId = 0; ws.onopen = () => { console.log('connected'); ws.send(JSON.stringify({ type: 'joinGroup', group: 'stream', ackId: ++ackId })); };
Comme vous pouvez le constater, le client rejoint le groupe en envoyant un message dans le type
joinGroup
.De même, mettez légèrement à jour la logique de rappel
ws.onmessage
pour analyser la réponse JSON et imprimer uniquement les messages provenant du groupestream
. Elle fait ainsi office d’imprimante de stream en direct.ws.onmessage = event => { let message = JSON.parse(event.data); if (message.type === 'message' && message.group === 'stream') { let d = document.createElement('span'); d.innerText = message.data; output.appendChild(d); window.scrollTo(0, document.body.scrollHeight); } };
Dans un souci de sécurité, un client ne peut par défaut pas publier sur un groupe ni s’y abonner par lui-même. Comme vous l’avez remarqué,
roles
est défini sur le client lors de la génération du jeton :Définissez
roles
quandGenerateClientAccessUri
dansStartup.cs
:service.GenerateClientAccessUri(roles: new string[] { "webpubsub.sendToGroup.stream", "webpubsub.joinLeaveGroup.stream" })
Enfin, appliquez également un style à
index.html
pour qu’il s’affiche correctement.<html> <head> <style> #output { white-space: pre; font-family: monospace; } </style> </head>
Maintenant, exécutez le code ci-dessous et tapez du texte. Il s’affiche dans le navigateur en temps réel :
ls -R | dotnet run
# Or call `dir /s /b | dotnet run` when you are using CMD under Windows
Vous pouvez également le ralentir pour voir que les données sont diffusées en temps réel dans le navigateur :
for i in $(ls -R); do echo $i; sleep 0.1; done | dotnet run
L’exemple de code complet de ce tutoriel est disponible ici.
Étapes suivantes
Ce tutoriel vous donne une idée de base de la procédure à suivre pour se connecter au service Web PubSub et publier des messages sur les clients connectés avec le sous-protocole.
Pour plus d’informations sur l’utilisation du service, consultez les autres tutoriels.