Partager via


Tutoriel : Créer une application de conversation sur un serveur Blazor Server

Ce tutoriel vous montre comment créer et modifier une application Blazor Server. Vous allez apprendre à effectuer les actions suivantes :

  • Créer une salle de conversation simple avec le modèle d’application Blazor Server.
  • Utiliser des composants Razor.
  • Utiliser la gestion des événements et la liaison de données dans des composants Razor.
  • Effectuer un déploiement rapide sur Azure App Service avec Visual Studio.
  • Migrer le service SignalR local vers Azure SignalR Service.

Prêt à commencer ?

Prérequis

Vous rencontrez des problèmes ? Dites-le nous.

Générer une salle de conversation locale dans une application Blazor Server

À compter de Visual Studio 2019 version 16.2.0, Azure SignalR Service est intégré au processus de publication d’application web pour faciliter la gestion des dépendances entre une application web et le service SignalR. Vous pouvez travailler dans les deux environnements simultanément sans apporter le moindre changement au code :

  • Au sein d’une instance locale de SignalR, dans un environnement de développement local.
  • Au sein d’Azure SignalR Service pour Azure App Service.
  1. Créez une application de conversation Blazor :

    1. Dans Visual Studio, choisissez Créer un projet.

    2. Sélectionnez Application Blazor.

    3. Nommez l’application et choisissez un dossier.

    4. Sélectionnez le modèle Application Blazor Server.

      Notes

      Vérifiez que vous avez déjà installé le SDK .NET Core 3.0+ pour permettre à Visual Studio de reconnaître correctement le framework cible.

      Dans Créer un projet, sélectionnez le modèle d’application Blazor.

    5. Vous pouvez également créer un projet en exécutant la commande dotnet new dans l’interface CLI .NET :

      dotnet new blazorserver -o BlazorChat
      
  2. Ajoutez un nouveau fichier C# nommé BlazorChatSampleHub.cs et créez une classe BlazorChatSampleHub dérivant de la classe Hub pour l’application de conversation. Pour plus d’informations sur la création de hubs, consultez Créer et utiliser des hubs.

    using System;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.SignalR;
    
    namespace BlazorChat
    {
        public class BlazorChatSampleHub : Hub
        {
            public const string HubUrl = "/chat";
    
            public async Task Broadcast(string username, string message)
            {
                await Clients.All.SendAsync("Broadcast", username, message);
            }
    
            public override Task OnConnectedAsync()
            {
                Console.WriteLine($"{Context.ConnectionId} connected");
                return base.OnConnectedAsync();
            }
    
            public override async Task OnDisconnectedAsync(Exception e)
            {
                Console.WriteLine($"Disconnected {e?.Message} {Context.ConnectionId}");
                await base.OnDisconnectedAsync(e);
            }
        }
    }
    
  3. Ajoutez un point de terminaison pour le hub dans la méthode Startup.Configure().

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Installez le package Microsoft.AspNetCore.SignalR.Client pour utiliser le client SignalR.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Pour implémenter le client SignalR, créez un composant Razor appelé ChatRoom.razor sous le dossier Pages. Utilisez le fichier ChatRoom.razor, ou suivez les étapes ci-dessous :

    1. Ajoutez la directive @page et les instructions using. Utilisez la directive @inject pour injecter le service NavigationManager.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. Dans la section @code, ajoutez les membres suivants au nouveau client SignalR pour envoyer et recevoir des messages.

      @code {
          // flag to indicate chat status
          private bool _isChatting = false;
      
          // name of the user who will be chatting
          private string _username;
      
          // on-screen message
          private string _message;
      
          // new message input
          private string _newMessage;
      
          // list of messages in chat
          private List<Message> _messages = new List<Message>();
      
          private string _hubUrl;
          private HubConnection _hubConnection;
      
          public async Task Chat()
          {
              // check username is valid
              if (string.IsNullOrWhiteSpace(_username))
              {
                  _message = "Please enter a name";
                  return;
              };
      
              try
              {
                  // Start chatting and force refresh UI.
                  _isChatting = true;
                  await Task.Delay(1);
      
                  // remove old messages if any
                  _messages.Clear();
      
                  // Create the chat client
                  string baseUrl = navigationManager.BaseUri;
      
                  _hubUrl = baseUrl.TrimEnd('/') + BlazorChatSampleHub.HubUrl;
      
                  _hubConnection = new HubConnectionBuilder()
                      .WithUrl(_hubUrl)
                      .Build();
      
                  _hubConnection.On<string, string>("Broadcast", BroadcastMessage);
      
                  await _hubConnection.StartAsync();
      
                  await SendAsync($"[Notice] {_username} joined chat room.");
              }
              catch (Exception e)
              {
                  _message = $"ERROR: Failed to start chat client: {e.Message}";
                  _isChatting = false;
              }
          }
      
          private void BroadcastMessage(string name, string message)
          {
              bool isMine = name.Equals(_username, StringComparison.OrdinalIgnoreCase);
      
              _messages.Add(new Message(name, message, isMine));
      
              // Inform blazor the UI needs updating
              InvokeAsync(StateHasChanged);
          }
      
          private async Task DisconnectAsync()
          {
              if (_isChatting)
              {
                  await SendAsync($"[Notice] {_username} left chat room.");
      
                  await _hubConnection.StopAsync();
                  await _hubConnection.DisposeAsync();
      
                  _hubConnection = null;
                  _isChatting = false;
              }
          }
      
          private async Task SendAsync(string message)
          {
              if (_isChatting && !string.IsNullOrWhiteSpace(message))
              {
                  await _hubConnection.SendAsync("Broadcast", _username, message);
      
                  _newMessage = string.Empty;
              }
          }
      
          private class Message
          {
              public Message(string username, string body, bool mine)
              {
                  Username = username;
                  Body = body;
                  Mine = mine;
              }
      
              public string Username { get; set; }
              public string Body { get; set; }
              public bool Mine { get; set; }
      
              public bool IsNotice => Body.StartsWith("[Notice]");
      
              public string CSS => Mine ? "sent" : "received";
          }
      }
      
    3. Ajoutez la balise d’interface utilisateur avant la section @code pour interagir avec le client SignalR.

      <h1>Blazor SignalR Chat Sample</h1>
      <hr />
      
      @if (!_isChatting)
      {
          <p>
              Enter your name to start chatting:
          </p>
      
          <input type="text" maxlength="32" @bind="@_username" />
          <button type="button" @onclick="@Chat"><span class="oi oi-chat" aria-hidden="true"></span> Chat!</button>
      
          // Error messages
          @if (_message != null)
          {
              <div class="invalid-feedback">@_message</div>
              <small id="emailHelp" class="form-text text-muted">@_message</small>
          }
      }
      else
      {
          // banner to show current user
          <div class="alert alert-secondary mt-4" role="alert">
              <span class="oi oi-person mr-2" aria-hidden="true"></span>
              <span>You are connected as <b>@_username</b></span>
              <button class="btn btn-sm btn-warning ml-md-auto" @onclick="@DisconnectAsync">Disconnect</button>
          </div>
          // display messages
          <div id="scrollbox">
              @foreach (var item in _messages)
              {
                  @if (item.IsNotice)
                  {
                      <div class="alert alert-info">@item.Body</div>
                  }
                  else
                  {
                      <div class="@item.CSS">
                          <div class="user">@item.Username</div>
                          <div class="msg">@item.Body</div>
                      </div>
                  }
              }
              <hr />
              <textarea class="input-lg" placeholder="enter your comment" @bind="@_newMessage"></textarea>
              <button class="btn btn-default" @onclick="@(() => SendAsync(_newMessage))">Send</button>
          </div>
      }
      
  6. Mettez à jour le composant NavMenu.razor pour insérer un nouveau composant NavLink à lier à la salle de conversation sous NavMenuCssClass.

    <li class="nav-item px-3">
        <NavLink class="nav-link" href="chatroom">
            <span class="oi oi-chat" aria-hidden="true"></span> Chat room
        </NavLink>
    </li>
    
  7. Ajoutez quelques classes CSS au fichier site.css pour styliser les éléments d’interface utilisateur dans la page de conversation.

    /* improved for chat text box */
    textarea {
        border: 1px dashed #888;
        border-radius: 5px;
        width: 80%;
        overflow: auto;
        background: #f7f7f7
    }
    
    /* improved for speech bubbles */
    .received, .sent {
        position: relative;
        font-family: arial;
        font-size: 1.1em;
        border-radius: 10px;
        padding: 20px;
        margin-bottom: 20px;
    }
    
    .received:after, .sent:after {
        content: '';
        border: 20px solid transparent;
        position: absolute;
        margin-top: -30px;
    }
    
    .sent {
        background: #03a9f4;
        color: #fff;
        margin-left: 10%;
        top: 50%;
        text-align: right;
    }
    
    .received {
        background: #4CAF50;
        color: #fff;
        margin-left: 10px;
        margin-right: 10%;
    }
    
    .sent:after {
        border-left-color: #03a9f4;
        border-right: 0;
        right: -20px;
    }
    
    .received:after {
        border-right-color: #4CAF50;
        border-left: 0;
        left: -20px;
    }
    
    /* div within bubble for name */
    .user {
        font-size: 0.8em;
        font-weight: bold;
        color: #000;
    }
    
    .msg {
        /*display: inline;*/
    }
    
  8. Pour exécuter l’application, appuyez sur F5. À présent, vous pouvez lancer la conversation :

    Une conversation animée entre Bob et Alice s’affiche. Alice dit Bonjour, Bob dit Salut.

Vous rencontrez des problèmes ? Dites-le nous.

Publication dans Azure

Quand vous déployez l’application Blazor sur Azure App Service, nous vous recommandons d’utiliser Azure SignalR Service. Azure SignalR Service permet d’effectuer un scale-up d’une application Blazor Server sur un grand nombre de connexions SignalR simultanées. De plus, la portée mondiale et les centres de données hautes performances du service SignalR contribuent à réduire considérablement la latence due aux zones géographiques.

Important

Dans une application Blazor Server, les états de l’interface utilisateur sont conservés côté serveur, ce qui signifie qu’une session de serveur persistante est nécessaire pour conserver un état. S’il existe un seul serveur d’applications, les sessions persistantes sont assurées de fait. Toutefois, si plusieurs serveurs d’applications sont utilisés, la négociation et la connexion du client peuvent être redirigées vers des serveurs différents, ce qui peut entraîner une gestion incohérente de l’état de l’IU dans une application Blazor. Il est donc recommandé d’activer les sessions serveur persistantes, comme indiqué dans appsettings.json :

"Azure:SignalR:ServerStickyMode": "Required"
  1. Cliquez avec le bouton droit sur le projet et accédez à Publier. Utilisez les paramètres suivants :

    • Cible : Azure
    • Cible spécifique : Tous les types Azure App Service sont pris en charge.
    • App service : Créez ou sélectionnez l’instance App Service.

    L’animation montre la sélection d’Azure comme cible, puis d’Azure App Service comme cible spécifique.

  2. Ajoutez la dépendance Azure SignalR Service.

    Après la création du profil de publication, un message de recommandation s’affiche pour ajouter Azure SignalR Service sous Dépendances de service. Sélectionnez Configurer pour créer une instante Azure SignalR Service ou en sélectionner une existante dans le volet.

    Dans Publier, le lien vers Configurer est mis en surbrillance.

    La dépendance de service effectue les activités suivantes pour permettre à votre application de basculer automatiquement vers Azure SignalR Service, une fois sur Azure :

    • Mettez à jour HostingStartupAssembly pour utiliser Azure SignalR Service.
    • Ajouter une référence de package NuGet Azure SignalR Service.
    • Mettre à jour les propriétés de profil pour enregistrer les paramètres de dépendance.
    • Configurer le magasin de secrets conformément à votre choix.
    • Ajouter la configuration dans appsettings.json pour que votre application cible Azure SignalR Service.

    Dans Récapitulatif des changements, les cases à cocher permettent de sélectionner toutes les dépendances.

  3. Publiez l’application.

    Votre application est maintenant prête à être publiée. Une fois le processus de publication terminé, l’application se lance automatiquement dans un navigateur.

    Notes

    Elle peut nécessiter un certain temps pour démarrer en raison de la latence observée au démarrage du déploiement d’Azure App Service. Vous pouvez utiliser les outils de débogage du navigateur (généralement en appuyant sur F12) pour vérifier que le trafic a été redirigé vers Azure SignalR Service.

    L’exemple de conversation Blazor SignalR est associé à une zone de texte pour votre nom et à un bouton Chat! (Conversation !) pour démarrer une conversation.

Vous rencontrez des problèmes ? Dites-le nous.

Activer Azure SignalR Service pour un développement local

  1. Ajoutez une référence au SDK Azure SignalR à l’aide de la commande suivante.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Ajoutez un appel à AddAzureSignalR() dans Startup.ConfigureServices(), comme le montre l’exemple suivant :

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Configurez la chaîne de connexion Azure SignalR Service dans appsettings.json ou en utilisant l’outil Secret Manager.

Notes

L’étape 2 peut être remplacée par la configuration d’assemblys de démarrage d’hébergement afin d’utiliser le SDK SignalR.

  1. Ajoutez la configuration pour activer Azure SignalR Service dans appsettings.json :

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string> 
      }
    }
    
    
  2. Affectez l’assembly de démarrage d’hébergement pour utiliser le SDK Azure SignalR. Modifiez launchSettings.json et ajoutez une configuration comme dans l’exemple suivant dans environmentVariables :

    "environmentVariables": {
        ...,
       "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.Azure.SignalR"
     }
    
    

Vous rencontrez des problèmes ? Dites-le nous.

Nettoyer les ressources

Pour supprimer les ressources créées à l’occasion de ce tutoriel, supprimez le groupe de ressources par le biais du portail Azure.

Ressources supplémentaires

Étapes suivantes

Dans ce didacticiel, vous avez appris à :

  • Créer une salle de conversation simple avec le modèle d’application Blazor Server.
  • Utiliser des composants Razor.
  • Utiliser la gestion des événements et la liaison de données dans des composants Razor.
  • Effectuer un déploiement rapide sur Azure App Service avec Visual Studio.
  • Migrer le service SignalR local vers Azure SignalR Service.

En savoir plus sur la haute disponibilité :