Démarrage rapide : Créer une salle de conversation à l'aide de SignalR Service

Azure SignalR Service est un service Azure qui permet aux développeurs de créer facilement des applications web avec des fonctionnalités en temps réel.

Cet article explique comment démarrer avec Azure SignalR Service. Dans ce guide de démarrage rapide, vous allez créer une application de conversation à l'aide d'une application web MVC ASP.NET Core. Cette application établira une connexion avec votre ressource Azure SignalR Service pour activer les mises à jour de contenu en temps réel. Vous hébergerez l'application web localement et vous connecterez à plusieurs clients de navigateur. Chaque client pourra envoyer (push) les mises à jour de contenus à tous les autres clients.

Vous pouvez utiliser l’éditeur de code de votre choix pour exécuter les étapes de ce démarrage rapide. L'option Visual Studio Code est disponible sur les plateformes Windows, macOS et Linux.

Le code de ce didacticiel est disponible au téléchargement dans le référentiel AzureSignalR-samples GitHub. Vous pouvez créer les ressources Azure utilisées dans ce guide de démarrage rapide en suivant la section Créer un script SignalR Service.

Si vous n’avez pas d’abonnement Azure, créez un compte gratuit avant de commencer.

Prêt à commencer ?

Prérequis

Vous rencontrez des problèmes ? Essayez le guide de résolution des problèmes ou faites-le nous savoir.

Créer une ressource Azure SignalR

Dans cette section, vous allez créer une instance Azure SignalR de base pour votre application. Les étapes suivantes utilisent le portail Azure pour créer une nouvelle instance, mais vous pouvez également utiliser Azure CLI. Pour plus d’informations sur la commande az signalr create, consultez la documentation de référence sur l’interface CLI Azure SignalR Service.

  1. Connectez-vous au portail Azure.
  2. En haut à gauche de la page, sélectionnez + Créer une ressource.
  3. Dans la page Créer une ressource, dans la zone de texte Rechercher dans les services et la Place de marché, entrez signalr, puis sélectionnez SignalR Service dans la liste.
  4. Dans la page SignalR Service, sélectionnez Créer.
  5. Sous l’onglet Informations de base, vous devez entrer les informations de base concernant votre nouvelle instance SignalR Service. Saisissez les valeurs suivantes :
Champ Valeur suggérée Description
Abonnement Choisir votre abonnement Sélectionnez l’abonnement que vous souhaitez utiliser pour créer une instance SignalR Service.
Groupe de ressources Créer un groupe de ressources nommé SignalRTestResources Sélectionnez ou créez un groupe de ressources pour votre ressource SignalR. Nous vous conseillons de créer un nouveau groupe de ressources pour ce tutoriel plutôt que d’utiliser un groupe existant. Pour libérer les ressources une fois le tutoriel terminé, supprimez le groupe de ressources.

La suppression du groupe de ressources supprimera également toutes les ressources qu’il contient. Cette action ne peut pas être annulée. Avant de supprimer un groupe de ressources, vérifiez qu’il ne contient pas des ressources que vous souhaitez conserver.

Pour plus d’informations, consultez Utilisation des groupes de ressources pour gérer vos ressources Azure.
Nom de la ressource testsignalr Entrez un nom de ressource unique à utiliser pour la ressource SignalR. Si le nom testsignalr a déjà été utilisé dans votre région, ajoutez un chiffre ou un caractère au nom pour le rendre unique.

Le nom doit être une chaîne de 1 à 63 caractères, et il ne peut contenir que des chiffres, des lettres et le caractère - (trait d'union). Le nom ne peut ni commencer ni se terminer par un trait d’union, et il n’accepte pas de traits d’union consécutifs.
Région Choisir votre région Sélectionnez la région appropriée pour votre nouvelle instance SignalR Service.

Azure SignalR Service n’est pas disponible dans toutes les régions. Pour plus d’informations, consultez Disponibilité d’Azure SignalR Service par région.
Niveau tarifaire Sélectionnez Modifier, puis choisissez Gratuit (Dev/Test uniquement). Choisissez Sélectionner pour confirmer votre choix de niveau tarifaire. Azure SignalR Service propose trois niveaux tarifaires : Gratuit, Standard et Premium. Les tutoriels utilisent le niveau Gratuit, sauf indication contraire dans les prérequis.

Pour plus d’informations sur les différences de fonctionnalités entre les niveaux et les tarifs, consultez Tarifs Azure SignalR Service.
Mode de service Choisir le mode de service approprié pour ce tutoriel Choisissez Valeur par défaut pour ASP.NET. Utilisez Serverless pour Azure Functions ou l’API REST.

Le mode Classique n’est pas utilisé dans les tutoriels Azure SignalR.

Pour plus d’informations, consultez Mode de service dans Azure SignalR Service.

Vous n’avez pas besoin de modifier les paramètres des onglets Réseau et Étiquettes pour les tutoriels SignalR.

  1. Sélectionnez le bouton Vérifier + créer au bas de l’onglet Informations de base.
  2. Sous l’onglet Vérifier + créer, passez en revue les valeurs, puis sélectionnez Créer. Le déploiement prend quelques instants.
  3. Une fois le déploiement terminé, sélectionnez le bouton Accéder à la ressource.
  4. Dans la page des ressources SignalR, sélectionnez Clés dans le menu de gauche sous Paramètres.
  5. Copiez la chaîne de connexion pour la clé primaire. Vous aurez besoin de cette chaîne de connexion pour configurer votre application plus loin dans ce tutoriel.

Créez une application web ASP.NET Core

Dans cette section, vous allez utiliser l'interface de ligne de commande (CLI) .NET Core pour créer un projet d'application web MVC ASP.NET Core. Par rapport à Visual Studio, l’interface CLI .NET Core offre l’avantage d’être disponible sur les plateformes Windows, macOS et Linux.

  1. Créez un dossier pour votre projet. Ce guide de démarrage rapide utilise le dossier E:\Testing\chattest.

  2. Dans le nouveau dossier, exécutez la commande suivante pour créer le projet :

    dotnet new web
    

Ajouter Secret Manager au projet

Dans cette section, vous allez ajouter l'outil Secret Manager à votre projet. L'outil Secret Manager stocke les données sensibles des travaux de développement à l'extérieur de l'arborescence de votre projet. Cette approche empêche le partage accidentel des secrets d'une application au sein du code source.

  1. Dans le dossier, initialisez UserSecretsId en exécutant la commande suivante :

    dotnet user-secrets init
    
  2. Ajoutez un secret nommé Azure:SignalR:ConnectionString à Secret Manager.

    Ce secret contiendra la chaîne de connexion pour accéder à votre ressource SignalR Service. Azure:SignalR:ConnectionString est la clé de configuration par défaut recherchée par SignalR pour établir une connexion. Dans la commande suivante, remplacez la valeur par la chaîne de connexion de votre ressource SignalR Service.

    Vous devez exécuter cette commande dans le répertoire où se trouve le fichier csproj.

    dotnet user-secrets set Azure:SignalR:ConnectionString "<Your connection string>"
    

    Secret Manager sera uniquement utilisé pour tester l'application web lorsque celle-ci est hébergée localement. Dans un prochain didacticiel, vous déploierez l'application web de conversation dans Azure. Une fois l'application web déployée dans Azure, vous utiliserez un paramètre d'application au lieu de stocker la chaîne de connexion avec Secret Manager.

    L'API de configuration permet d'accéder à ce secret. Avec l'API de configuration, un signe deux-points (:) fonctionne dans le nom de configuration sur toutes les plateformes prises en charge. Consultez Configuration par environnement.

Ajouter Azure SignalR à l’application web

  1. Ajoutez une référence au package NuGet Microsoft.Azure.SignalR en exécutant la commande suivante :

    dotnet add package Microsoft.Azure.SignalR
    
  2. Ouvrez Program.cs, puis mettez à jour le code sur l’extrait de code suivant ; le programme appelle les méthodes AddSignalR() et AddAzureSignalR() pour utiliser Azure SignalR Service :

    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddSignalR().AddAzureSignalR();
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseRouting();
    app.UseStaticFiles();
    app.MapHub<ChatSampleHub>("/chat");
    app.Run();
    

    Si le paramètre n’est pas transmis à AddAzureSignalR(), cela signifie que le programme utilise la clé de configuration par défaut de la chaîne de connexion à la ressource SignalR Service. La clé de configuration par défaut est Azure:SignalR:ConnectionString. Il utilise également ChatHub que nous allons créer dans la section ci-dessous.

Ajouter une classe de concentrateur

Dans SignalR, un concentrateur est un composant qui expose un ensemble de méthodes pouvant être appelées par le client. Dans cette section, vous définissez une classe de concentrateur avec deux méthodes :

  • BroadcastMessage: cette méthode envoie un message à tous les clients.
  • Echo: cette méthode renvoie un message à l’appelant.

Ces deux méthodes utilisent l'interface Clients fournie par le kit de développement logiciel (SDK) SignalR ASP.NET Core. Cette interface vous permet d'accéder à tous les clients connectés pour envoyer (push) le contenu de votre choix à vos clients.

  1. Dans le répertoire de votre projet, ajoutez un nouveau dossier nommé Hub. Ajoutez un nouveau fichier de code de hub nommé ChatHub.cs au nouveau dossier.

  2. Ajoutez le code suivant au fichier ChatSampleHub.cs pour définir votre classe de hub, puis enregistrez le fichier.

    using Microsoft.AspNetCore.SignalR;
    
    public class ChatSampleHub : Hub
    {
        public Task BroadcastMessage(string name, string message) =>
            Clients.All.SendAsync("broadcastMessage", name, message);
    
        public Task Echo(string name, string message) =>
            Clients.Client(Context.ConnectionId)
                    .SendAsync("echo", name, $"{message} (echo from server)");
    }
    

Ajouter l'interface du client de l'application web

L'interface utilisateur du client de cette application de salle de conversation sera composée d'éléments HTML et JavaScript enregistrés dans un fichier index.html figurant dans le répertoire wwwroot.

Copiez le fichier css/site.css situé dans le dossier wwwroot du référentiel d'exemples. Remplacez le fichier css/site.css de votre projet par celui que vous avez copié.

Créez dans le répertoire wwwroot un nouveau fichier nommé index.html, puis copiez et collez le code HTML suivant dans le fichier nouvellement créé.

<!DOCTYPE html>
<html>
<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <title>Azure SignalR Group Chat</title>
</head>
<body>
    <h2 class="text-center" style="margin-top: 0; padding-top: 30px; padding-bottom: 30px;">Azure SignalR Group Chat</h2>
    <div class="container" style="height: calc(100% - 110px);">
        <div id="messages" style="background-color: whitesmoke; "></div>
        <div style="width: 100%; border-left-style: ridge; border-right-style: ridge;">
            <textarea id="message"
                      style="width: 100%; padding: 5px 10px; border-style: hidden;"
                      placeholder="Type message and press Enter to send..."></textarea>
        </div>
        <div style="overflow: auto; border-style: ridge; border-top-style: hidden;">
            <button class="btn-warning pull-right" id="echo">Echo</button>
            <button class="btn-success pull-right" id="sendmessage">Send</button>
        </div>
    </div>
    <div class="modal alert alert-danger fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <div>Connection Error...</div>
                    <div><strong style="font-size: 1.5em;">Hit Refresh/F5</strong> to rejoin. ;)</div>
                </div>
            </div>
        </div>
    </div>

    <!--Reference the SignalR library. -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
    
    <!--Add script to update the page and send messages.-->
    <script type="text/javascript">
        document.addEventListener('DOMContentLoaded', function () {

            const generateRandomName = () =>
                Math.random().toString(36).substring(2, 10);

            let username = generateRandomName();
            const promptMessage = 'Enter your name:';
            do {
                username = prompt(promptMessage, username);
                if (!username || username.startsWith('_') || username.indexOf('<') > -1 || username.indexOf('>') > -1) {
                    username = '';
                    promptMessage = 'Invalid input. Enter your name:';
                }
            } while (!username)

            const messageInput = document.getElementById('message');
            messageInput.focus();

            function createMessageEntry(encodedName, encodedMsg) {
                var entry = document.createElement('div');
                entry.classList.add("message-entry");
                if (encodedName === "_SYSTEM_") {
                    entry.innerHTML = encodedMsg;
                    entry.classList.add("text-center");
                    entry.classList.add("system-message");
                } else if (encodedName === "_BROADCAST_") {
                    entry.classList.add("text-center");
                    entry.innerHTML = `<div class="text-center broadcast-message">${encodedMsg}</div>`;
                } else if (encodedName === username) {
                    entry.innerHTML = `<div class="message-avatar pull-right">${encodedName}</div>` +
                        `<div class="message-content pull-right">${encodedMsg}<div>`;
                } else {
                    entry.innerHTML = `<div class="message-avatar pull-left">${encodedName}</div>` +
                        `<div class="message-content pull-left">${encodedMsg}<div>`;
                }
                return entry;
            }

            function bindConnectionMessage(connection) {
                var messageCallback = function (name, message) {
                    if (!message) return;
                    var encodedName = name;
                    var encodedMsg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
                    var messageEntry = createMessageEntry(encodedName, encodedMsg);

                    var messageBox = document.getElementById('messages');
                    messageBox.appendChild(messageEntry);
                    messageBox.scrollTop = messageBox.scrollHeight;
                };
                connection.on('broadcastMessage', messageCallback);
                connection.on('echo', messageCallback);
                connection.onclose(onConnectionError);
            }

            function onConnected(connection) {
                console.log('connection started');
                connection.send('broadcastMessage', '_SYSTEM_', username + ' JOINED');
                document.getElementById('sendmessage').addEventListener('click', function (event) {
                    if (messageInput.value) {
                        connection.send('broadcastMessage', username, messageInput.value);
                    }

                    messageInput.value = '';
                    messageInput.focus();
                    event.preventDefault();
                });
                document.getElementById('message').addEventListener('keypress', function (event) {
                    if (event.keyCode === 13) {
                        event.preventDefault();
                        document.getElementById('sendmessage').click();
                        return false;
                    }
                });
                document.getElementById('echo').addEventListener('click', function (event) {
                    connection.send('echo', username, messageInput.value);

                    messageInput.value = '';
                    messageInput.focus();
                    event.preventDefault();
                });
            }

            function onConnectionError(error) {
                if (error && error.message) {
                    console.error(error.message);
                }
                var modal = document.getElementById('myModal');
                modal.classList.add('in');
                modal.style = 'display: block;';
            }

            const connection = new signalR.HubConnectionBuilder()
                .withUrl('/chat')
                .build();
            bindConnectionMessage(connection);
            connection.start()
                .then(() => onConnected(connection))
                .catch(error => console.error(error.message));
        });
    </script>
</body>
</html>

Le code du fichier index.html appelle pour établir une connexion HTTP avec la ressource Azure SignalR.

Si elle est établie, cette connexion est passée à bindConnectionMessage, qui ajoute des gestionnaires d’événements pour le contenu entrant envoyé (push) au client.

HubConnection.start() lance la communication avec le concentrateur. onConnected() ajoute ensuite les gestionnaires d'événements des boutons. Ces gestionnaires utilisent la connexion pour permettre à ce client d’envoyer (push) des mises à jour de contenu à tous les clients connectés.

Générer et exécuter l’application localement

  1. Exécutez la commande suivante pour exécuter l’application localement :

    dotnet run
    

    L’application sera hébergée localement avec une sortie contenant l’URL localhost, par exemple, comme suit :

    Building...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: http://localhost:5000
    info: Microsoft.Hosting.Lifetime[0]
          Application started. Press Ctrl+C to shut down.
    info: Microsoft.Hosting.Lifetime[0]
          Hosting environment: Development
    
  2. Ouvrez deux fenêtres de navigateur. Dans chaque navigateur, accédez à l’URL localhost affichée dans la fenêtre de sortie, par exemple, http://localhost:5000/ comme le montre la fenêtre de sortie ci-dessus. Vous êtes invité à entrer votre nom. Entrez un nom pour les clients, puis testez l'envoi (push) d'un message entre les deux clients à l'aide du bouton Envoyer.

    Exemple de conversation de groupe Azure SignalR

Nettoyer les ressources

Si vous envisagez d'exécuter le didacticiel suivant, vous pouvez conserver les ressources créées dans le cadre de ce guide de démarrage rapide afin de les réutiliser.

Si vous en avez terminé avec l'exemple d'application de ce guide de démarrage rapide, supprimez les ressources Azure que vous avez créées afin d'éviter des frais.

Important

La suppression d'un groupe de ressources est irréversible et inclut toutes les ressources de ce groupe. Veillez à ne pas supprimer accidentellement les mauvaises ressources ou le mauvais groupe de ressources. Si vous avez créé les ressources de cet échantillon dans un groupe de ressources existant contenant des ressources que vous souhaitez conserver, vous pouvez supprimer chaque ressource individuellement à partir de son panneau, au lieu de supprimer l’intégralité du groupe de ressources.

Connectez-vous au portail Azure, puis sélectionnez Groupes de ressources.

Dans la zone de texte Filtrer par nom, saisissez le nom de votre groupe de ressources. Les instructions relatives à ce démarrage rapide utilisaient un groupe de ressources nommé SignalRTestResources. Sur votre groupe de ressources dans la liste des résultats, sélectionnez les points de suspension (), puis Supprimer le groupe de ressources.

Sélections pour la suppression d'un groupe de ressources

Vous êtes invité à confirmer la suppression du groupe de ressources. Entrez le nom de votre groupe de ressources à confirmer, puis sélectionnez Supprimer.

Après quelques instants, le groupe de ressources et toutes ses ressources sont supprimés.

Vous rencontrez des problèmes ? Essayez le guide de résolution des problèmes ou faites-le nous savoir.

Étapes suivantes

Dans le cadre de ce guide de démarrage rapide, vous avez créé une ressource Azure SignalR Service. Vous l’avez ensuite utilisée avec une application web ASP.NET Core pour envoyer (push) des mises à jour de contenu en temps réel à plusieurs clients connectés. Pour en savoir plus sur l'utilisation d'Azure SignalR Service, accédez au didacticiel qui présente l'authentification.