Delen via


Zelfstudie: Een Blazor Server-chat-app bouwen

In deze zelfstudie wordt uitgelegd hoe u een Blazor Server-app bouwt en wijzigt. U leert het volgende:

  • Bouw een eenvoudige chatruimte met de Blazor Server-app-sjabloon.
  • Werken met Razor-onderdelen.
  • Gebruik gebeurtenisafhandeling en gegevensbinding in Razor-onderdelen.
  • Snel implementeren in Azure-app Service in Visual Studio.
  • Migreren van lokale SignalR naar Azure SignalR Service.

Klaar om aan de slag te gaan?

Vereisten

Ondervindt u problemen? Laat het ons weten.

Een lokale chatroom bouwen in Blazor Server-app

Vanaf Visual Studio 2019 versie 16.2.0 is Azure SignalR Service ingebouwd in het publicatieproces van de webtoepassing om het beheren van de afhankelijkheden tussen de web-app en SignalR-service veel handiger te maken. U kunt zonder codewijzigingen tegelijk werken:

  • in een lokaal SignalR-exemplaar, in een lokale ontwikkelomgeving.
  • in Azure SignalR Service voor Azure-app Service.
  1. Een Blazor-chat-app maken:

    1. Kies een nieuw project maken in Visual Studio.

    2. Selecteer Blazor-app.

    3. Geef de toepassing een naam en kies een map.

    4. Selecteer de blazor Server-app-sjabloon .

      Notitie

      Zorg ervoor dat u .NET Core SDK 3.0+ al hebt geïnstalleerd om Visual Studio in te schakelen om het doelframework correct te herkennen.

      Selecteer in Een nieuw project maken de Blazor-app-sjabloon.

    5. U kunt ook een project maken door de dotnet new opdracht uit te voeren in de .NET CLI:

      dotnet new blazorserver -o BlazorChat
      
  2. Voeg een nieuw C#-bestand toe met de naam BlazorChatSampleHub.cs en maak een nieuwe klasse BlazorChatSampleHub die is afgeleid van de Hub klasse voor de chat-app. Zie Hubs maken en gebruiken voor meer informatie over het maken van 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. Voeg een eindpunt toe voor de hub in de Startup.Configure() methode.

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Installeer het Microsoft.AspNetCore.SignalR.Client pakket om de SignalR-client te gebruiken.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Als u de SignalR-client wilt implementeren, maakt u een nieuw Razor-onderdeel dat wordt aangeroepen ChatRoom.razor onder de Pages map. Gebruik het bestand ChatRoom.razor of voer de volgende stappen uit:

    1. Voeg de @page instructie en de using-instructies toe. Gebruik de @inject instructie om de NavigationManager service te injecteren.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. Voeg in de @code sectie de volgende leden toe aan de nieuwe SignalR-client om berichten te verzenden en te ontvangen.

      @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. Voeg de ui-markeringen toe vóór de @code sectie om te communiceren met de SignalR-client.

      <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. Werk het NavMenu.razor onderdeel bij om een nieuw NavLink onderdeel in te voegen dat u wilt koppelen aan de chatruimte onder 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. Voeg enkele CSS-klassen toe aan het site.css bestand om de ui-elementen in de chatpagina te stylen.

    /* 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. Druk op F5 om de app uit te voeren. U kunt nu de chat initiëren:

    Er wordt een geanimeerde chat tussen Bob en Alice weergegeven. Alice zegt Hallo, Bob zegt Hallo.

Ondervindt u problemen? Laat het ons weten.

Publiceren naar Azure

Wanneer u de Blazor-app implementeert in Azure-app Service, wordt u aangeraden Azure SignalR Service te gebruiken. Met Azure SignalR Service kunt u een Blazor Server-app omhoog schalen naar een groot aantal gelijktijdige SignalR-verbindingen. Bovendien helpen de wereldwijde bereik- en prestatiedatacentra van SignalR aanzienlijk bij het verminderen van de latentie vanwege geografie.

Belangrijk

In een Blazor Server-app worden de UI-statussen aan de serverzijde gehandhaafd. Dit betekent dat er een plakserversessie nodig is om de status te behouden. Als er één app-server is, worden plaksessies standaard gegarandeerd. Als er echter meerdere app-servers in gebruik zijn, kan de clientonderhandeling en -verbinding worden omgeleid naar verschillende servers, wat kan leiden tot een inconsistent ui-statusbeheer in een Blazor-app. Daarom wordt aanbevolen om plakserversessies in te schakelen, zoals wordt weergegeven in appsettings.json:

"Azure:SignalR:ServerStickyMode": "Required"
  1. Klik met de rechtermuisknop op het project en ga naar Publiceren. Gebruik de volgende instellingen:

    • Doel: Azure
    • Specifiek doel: alle typen Azure-app Service worden ondersteund.
    • App Service: het App Service-exemplaar maken of selecteren.

    In de animatie ziet u de selectie van Azure als doel en Azure-app Serice als specifiek doel.

  2. Voeg de Azure SignalR Service-afhankelijkheid toe.

    Nadat het publicatieprofiel is gemaakt, ziet u een aanbevelingsbericht om de Azure SignalR-service toe te voegen onder Serviceafhankelijkheden. Selecteer Configureren om een nieuwe te maken of selecteer een bestaande Azure SignalR-service in het deelvenster.

    Bij Publiceren is de koppeling naar Configureren gemarkeerd.

    De serviceafhankelijkheid voert de volgende activiteiten uit om uw app in staat te stellen automatisch over te schakelen naar Azure SignalR Service wanneer deze zich in Azure bevindt:

    • Werk HostingStartupAssembly bij om de Azure SignalR Service te gebruiken.
    • Voeg de NuGet-pakketreferentie voor Azure SignalR Service toe.
    • Werk de profieleigenschappen bij om de afhankelijkheidsinstellingen op te slaan.
    • Configureer het geheimenarchief op basis van uw keuze.
    • Voeg de configuratie toe in appsettings.json om uw app-doel te maken voor Azure SignalR Service.

    In het overzicht van wijzigingen worden de selectievakjes gebruikt om alle afhankelijkheden te selecteren.

  3. Publiceer de app.

    De app is nu gereed om te worden gepubliceerd. Wanneer het publicatieproces is voltooid, wordt de app automatisch gestart in een browser.

    Notitie

    Het kan enige tijd duren voordat de app wordt gestart vanwege de latentie van de Azure-app Service-implementatie. U kunt de hulpprogramma's voor foutopsporingsprogramma's van de browser gebruiken (meestal door op F12 te drukken) om ervoor te zorgen dat het verkeer is omgeleid naar Azure SignalR Service.

    Blazor SignalR Chat Sample heeft een tekstvak voor uw naam en een chat! om een chat te starten.

Ondervindt u problemen? Laat het ons weten.

Azure SignalR Service inschakelen voor lokale ontwikkeling

  1. Voeg een verwijzing toe naar de Azure SignalR SDK met behulp van de volgende opdracht.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Voeg een aanroep toe AddAzureSignalR() Startup.ConfigureServices() , zoals wordt weergegeven in het volgende voorbeeld:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Configureer de Azure SignalR Service-verbindingsreeks in appsettings.json of met behulp van het hulpprogramma Secret Manager.

Notitie

Stap 2 kan worden vervangen door het configureren van hosting-opstartassembly's voor het gebruik van de SignalR SDK.

  1. Voeg de configuratie toe om Azure SignalR Service in te schakelen in appsettings.json:

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string> 
      }
    }
    
    
  2. Configureer de hosting-opstartassembly voor het gebruik van de Azure SignalR SDK. Bewerk launchSettings.json en voeg een configuratie toe zoals in het volgende voorbeeld:environmentVariables

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

Ondervindt u problemen? Laat het ons weten.

Resources opschonen

Als u de in deze zelfstudie gemaakte resources wilt opschonen, verwijdert u de resourcegroep met Azure Portal.

Aanvullende bronnen

Volgende stappen

In deze zelfstudie heeft u het volgende geleerd:

  • Bouw een eenvoudige chatruimte met de Blazor Server-app-sjabloon.
  • Werken met Razor-onderdelen.
  • Gebruik gebeurtenisafhandeling en gegevensbinding in Razor-onderdelen.
  • Snel implementeren in Azure-app Service in Visual Studio.
  • Migreren van lokale SignalR naar Azure SignalR Service.

Meer informatie over hoge beschikbaarheid: