Condividi tramite


Esercitazione: Creare un'app di chat Blazor Server

Questa esercitazione illustra come creare e modificare un'app Blazor Server. Scopri come:

  • Creare una chat room semplice con il modello di app Blazor Server.
  • Usare i componenti Razor.
  • Usare la gestione degli eventi e il data binding nei componenti Razor.
  • Eseguire rapidamente la distribuzione nel Servizio app di Azure in Visual Studio.
  • Eseguire la migrazione da SignalR locale al Servizio Azure SignalR.

Importante

Le stringa di connessione non elaborate vengono visualizzate in questo articolo solo a scopo dimostrativo.

Un stringa di connessione include le informazioni di autorizzazione necessarie per consentire all'applicazione di accedere alle Servizio Azure SignalR. La chiave di accesso all'interno della stringa di connessione è simile a una password radice per il servizio. Negli ambienti di produzione proteggere sempre le chiavi di accesso. Usare Azure Key Vault per gestire e ruotare le chiavi in modo sicuro e proteggere i stringa di connessione usando Microsoft Entra ID e autorizzare l'accesso con Microsoft Entra ID.

Evitare di distribuire le chiavi di accesso ad altri utenti, impostarle come hardcoded o salvarle in un file di testo normale accessibile ad altri. Ruotare le chiavi se si ritiene che siano state compromesse.

Pronti a iniziare?

Prerequisiti

Problemi? Segnalarli.

Creare una chat room locale nell'app Blazor Server

A partire da Visual Studio 2019 versione 16.2.0, il Servizio Azure SignalR è integrato nel processo di pubblicazione delle applicazioni Web per semplificare la gestione delle dipendenze tra l'app Web e il Servizio SignalR. È possibile lavorare senza modifiche al codice contemporaneamente:

  • In un'istanza locale di SignalR, in un ambiente di sviluppo locale.
  • Nel Servizio Azure SignalR per il Servizio app di Azure.
  1. Creare un'app Blazor di chat:

    1. In Visual Studio scegliere Crea un nuovo progetto.

    2. Selezionare App Blazor.

    3. Assegnare un nome all'applicazione e scegliere una cartella.

    4. Selezionare il modello App Blazor Server.

      Nota

      Assicurarsi di aver già installato .NET Core SDK 3.0+ per consentire a Visual Studio di riconoscere correttamente il framework di destinazione.

      In Crea un nuovo progetto selezionare il modello App Blazor.

    5. È anche possibile creare un progetto eseguendo il comando dotnet new nell'interfaccia della riga di comando di .NET:

      dotnet new blazorserver -o BlazorChat
      
  2. Aggiungere un nuovo file C# denominato BlazorChatSampleHub.cs e creare una nuova classe BlazorChatSampleHub derivante dalla classe Hub per l'app di chat. Per altre informazioni sulla creazione di hub, vedere Creare e usare hub.

    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. Aggiungere un endpoint per l'hub nel metodo Startup.Configure().

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Installare il pacchetto Microsoft.AspNetCore.SignalR.Client per usare il client SignalR.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Per implementare il client SignalR, creare un nuovo componente Razor denominato ChatRoom.razor nella cartella Pages. Usare il file ChatRoom.razor o seguire questa procedura:

    1. Aggiungere la direttiva @page e le istruzioni using. Usare la direttiva @inject per inserire il servizio NavigationManager.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. Nella sezione @code aggiungere i membri seguenti al nuovo client SignalR per inviare e ricevere messaggi.

      @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. Aggiungere il markup dell'interfaccia utente prima della sezione @code per interagire con il 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. Aggiornare il componente NavMenu.razor per inserire un nuovo componente NavLink per collegarsi alla chat room in 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. Aggiungere alcune classi CSS al file site.css per applicare uno stile agli elementi dell'interfaccia utente nella pagina della chat.

    /* 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. Per eseguire l'app, premere F5. È ora possibile avviare la chat:

    Viene visualizzata una chat animata tra Bob e Alice. Alice dice Salve, Bob dice Ciao.

Problemi? Segnalarli.

Pubblicare in Azure

Quando si distribuisce l'app Blazor nel Servizio app di Azure, è consigliabile usare il Servizio Azure SignalR. Il Servizio Azure SignalR consente di aumentare le prestazioni di un'app Blazor Server a un numero elevato di connessioni SignalR simultanee. Inoltre, la copertura globale del Servizio SignalR e i data center a prestazioni elevate consentono di ridurre in modo significativo la latenza dovuta alla geografia.

Importante

In un'app Blazor Server gli stati dell'interfaccia utente vengono mantenuti sul lato server, il che significa che è necessaria una sessione server permanente per mantenere lo stato. Se è presente un singolo server app, le sessioni permanenti vengono assicurate dalla progettazione. Tuttavia, se sono in uso più server app, la negoziazione e la connessione client possono essere reindirizzate a server diversi, il che può causare una gestione incoerente dello stato dell'interfaccia utente in un'app Blazor. Di conseguenza, è consigliabile abilitare sessioni server permanenti, come illustrato in appsettings.json:

"Azure:SignalR:ServerStickyMode": "Required"
  1. Fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica. Usare le seguenti impostazioni:

    • Destinazione: Azure
    • Destinazione specifica: sono supportati tutti i tipi di Servizio app di Azure.
    • Servizio app: creare o selezionare l'istanza del Servizio app.

    L'animazione mostra la selezione di Azure come destinazione e quindi app Azure Servizio come destinazione specifica.

  2. Aggiungere la dipendenza del Servizio Azure SignalR.

    Dopo la creazione del profilo di pubblicazione, è possibile visualizzare un messaggio di raccomandazione per aggiungere il Servizio Azure SignalR in Dipendenze del servizio. Selezionare Configura per creare una nuova istanza o selezionare un'istanza esistente del Servizio Azure SignalR nel riquadro.

    In Pubblica è evidenziato il collegamento a Configura.

    La dipendenza del servizio esegue le attività seguenti per consentire all'app di passare automaticamente al Servizio Azure SignalR quando è in Azure:

    • Aggiornare HostingStartupAssembly per usare il servizio Azure SignalR.
    • Aggiungere il riferimento al pacchetto NuGet del Servizio Azure SignalR.
    • Aggiornare le proprietà del profilo per salvare le impostazioni della dipendenza.
    • Configurare l'archivio dei segreti in base all'opzione scelta.
    • Aggiungere la configurazione in appsettings.json per fare in modo che l'app usi come destinazione il Servizio Azure SignalR.

    Nel riepilogo delle modifiche le caselle di controllo consentono di selezionare tutte le dipendenze.

  3. Pubblica l'app.

    L'app è ora pronta per la pubblicazione. Al termine del processo di pubblicazione, l'app viene avviata automaticamente in un browser.

    Nota

    L'avvio dell'app potrebbe richiedere tempo a causa della latenza di avvio della distribuzione del Servizio app di Azure. È possibile usare gli strumenti del debugger del browser (in genere premendo F12) per assicurarsi che il traffico sia stato reindirizzato al Servizio Azure SignalR.

    Esempio di chat di Blazor SignalR con una casella di testo in cui inserire il nome e un pulsante Chat! per avviare una chat.

Problemi? Segnalarli.

Abilitare il Servizio Azure SignalR per lo sviluppo locale

  1. Aggiungere un riferimento ad Azure SignalR SDK usando il comando seguente.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Aggiungere una chiamata a AddAzureSignalR() in Startup.ConfigureServices(), come illustrato nell'esempio seguente:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Configurare la stringa di connessione del Servizio Azure SignalR in appsettings.json o usando lo strumento Secret Manager.

Nota

Il passaggio 2 può essere sostituito con la configurazione di Assembly di avvio dell'hosting per l'uso di SignalR SDK.

  1. Aggiungere la configurazione per attivare Servizio Azure SignalR in appsettings.json.

    Le stringa di connessione non elaborate vengono visualizzate in questo articolo solo a scopo dimostrativo. Negli ambienti di produzione proteggere sempre le chiavi di accesso. Usare Azure Key Vault per gestire e ruotare le chiavi in modo sicuro e proteggere i stringa di connessione usando Microsoft Entra ID e autorizzare l'accesso con Microsoft Entra ID.

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string> 
      }
    }
    
    
  2. Configurare l'assembly di avvio dell'hosting per l'uso di Azure SignalR SDK. Modificare launchSettings.json e aggiungere una configurazione simile all'esempio seguente all'interno di environmentVariables:

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

Problemi? Segnalarli.

Pulire le risorse

Per pulire le risorse create in questa esercitazione, eliminare il gruppo di risorse usando il portale di Azure.

Risorse aggiuntive

Passaggi successivi

Questa esercitazione ha descritto come:

  • Creare una chat room semplice con il modello di app Blazor Server.
  • Usare i componenti Razor.
  • Usare la gestione degli eventi e il data binding nei componenti Razor.
  • Eseguire rapidamente la distribuzione nel Servizio app di Azure in Visual Studio.
  • Eseguire la migrazione da SignalR locale al Servizio Azure SignalR.

Leggere altre informazioni sulla disponibilità elevata: