Dela via


Självstudie: Skapa en Blazor Server-chattapp

Den här självstudien visar hur du skapar och ändrar en Blazor Server-app. Du lär dig att:

  • Skapa ett enkelt chattrum med Blazor Server-appmallen.
  • Arbeta med Razor-komponenter.
  • Använd händelsehantering och databindning i Razor-komponenter.
  • Snabbdistribution till Azure App Service i Visual Studio.
  • Migrera från lokal SignalR till Azure SignalR Service.

Är du redo att börja?

Förutsättningar

Har du problem? Berätta för oss.

Skapa ett lokalt chattrum i Blazor Server-appen

Från och med Visual Studio 2019 version 16.2.0 är Azure SignalR Service inbyggt i publiceringsprocessen för webbprogram för att göra det mycket enklare att hantera beroendena mellan webbappen och SignalR-tjänsten. Du kan arbeta utan några kodändringar samtidigt:

  • i en lokal SignalR-instans i en lokal utvecklingsmiljö.
  • i Azure SignalR Service för Azure App Service.
  1. Skapa en Blazor-chattapp:

    1. I Visual Studio väljer du Skapa ett nytt projekt.

    2. Välj Blazor App.

    3. Namnge programmet och välj en mapp.

    4. Välj mallen Blazor Server App .

      Kommentar

      Kontrollera att du redan har installerat .NET Core SDK 3.0+ så att Visual Studio kan identifiera målramverket korrekt.

      I Skapa ett nytt projekt väljer du blazor-appmallen.

    5. Du kan också skapa ett projekt genom att dotnet new köra kommandot i .NET CLI:

      dotnet new blazorserver -o BlazorChat
      
  2. Lägg till en ny C#-fil med namnet BlazorChatSampleHub.cs och skapa en ny klass BlazorChatSampleHub som härleds från Hub klassen för chattappen. Mer information om hur du skapar hubbar finns i Skapa och använda hubbar.

    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. Lägg till en slutpunkt för hubben i Startup.Configure() -metoden.

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Microsoft.AspNetCore.SignalR.Client Installera paketet för att använda SignalR-klienten.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Om du vill implementera SignalR-klienten skapar du en ny Razor-komponent som heter ChatRoom.razor under Pages mappen . Använd filen ChatRoom.razor eller utför följande steg:

    1. @page Lägg till direktivet och användningssatserna. @inject Använd direktivet för att mata in NavigationManager tjänsten.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. I avsnittet @code lägger du till följande medlemmar i den nya SignalR-klienten för att skicka och ta emot meddelanden.

      @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. Lägg till UI-markering före @code avsnittet för att interagera med SignalR-klienten.

      <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. Uppdatera komponenten NavMenu.razor för att infoga en ny NavLink komponent för att länka till chattrummet under 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. Lägg till några CSS-klasser i site.css filen för att formatera användargränssnittselementen på chattsidan.

    /* 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. Tryck på F5 för att köra appen. Nu kan du starta chatten:

    En animerad chatt mellan Bob och Alice visas. Alice säger Hej, Bob säger Hej.

Har du problem? Berätta för oss.

Publicera till Azure

När du distribuerar Blazor-appen till Azure App Service rekommenderar vi att du använder Azure SignalR Service. Med Azure SignalR Service kan du skala upp en Blazor Server-app till ett stort antal samtidiga SignalR-anslutningar. Dessutom bidrar SignalR-tjänstens globala räckvidds- och högpresterande datacenter avsevärt till att minska svarstiden på grund av geografi.

Viktigt!

I en Blazor Server-app underhålls användargränssnittstillstånd på serversidan, vilket innebär att en klibbig serversession krävs för att bevara tillståndet. Om det finns en enda appserver säkerställs klibbiga sessioner avsiktligt. Men om flera appservrar används kan klientförhandlingen och anslutningen omdirigeras till olika servrar, vilket kan leda till en inkonsekvent UI-tillståndshantering i en Blazor-app. Därför rekommenderar vi att du aktiverar klibbiga serversessioner enligt appsettings.json:

"Azure:SignalR:ServerStickyMode": "Required"
  1. Högerklicka på projektet och gå till Publicera. Använd följande inställningar:

    • Mål: Azure
    • Specifikt mål: Alla typer av Azure App Service stöds.
    • App Service: Skapa eller välj App Service-instansen.

    Animeringen visar valet av Azure som mål och sedan Azure App Serice som specifikt mål.

  2. Lägg till Azure SignalR Service-beroendet.

    När du har skapat publiceringsprofilen kan du se ett rekommendationsmeddelande om att lägga till Azure SignalR-tjänsten under Tjänstberoenden. Välj Konfigurera för att skapa en ny eller välj en befintlig Azure SignalR Service i fönstret.

    På Publicera är länken till Konfigurera markerad.

    Tjänstberoendet utför följande aktiviteter för att göra det möjligt för din app att automatiskt växla till Azure SignalR Service när den är i Azure:

    • Uppdatera HostingStartupAssembly för att använda Azure SignalR Service.
    • Lägg till NuGet-paketreferensen för Azure SignalR Service.
    • Uppdatera profilegenskaperna för att spara beroendeinställningarna.
    • Konfigurera hemlighetsarkivet enligt ditt val.
    • Lägg till konfigurationen i appsettings.json för att göra din app till Azure SignalR Service som mål.

    I Sammanfattning av ändringar används kryssrutorna för att markera alla beroenden.

  3. Publicera appen.

    Nu är appen redo att publiceras. När publiceringsprocessen är klar startas appen automatiskt i en webbläsare.

    Kommentar

    Appen kan kräva lite tid för att starta på grund av startsvarstiden för Azure App Service-distributionen. Du kan använda webbläsarens felsökningsverktyg (vanligtvis genom att trycka på F12) för att säkerställa att trafiken har omdirigerats till Azure SignalR Service.

    Blazor SignalR Chat Sample har en textruta för ditt namn och en chatt! för att starta en chatt.

Har du problem? Berätta för oss.

Aktivera Azure SignalR Service för lokal utveckling

  1. Lägg till en referens till Azure SignalR SDK med hjälp av följande kommando.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Lägg till ett anrop till AddAzureSignalR() i Startup.ConfigureServices() enligt följande exempel:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Konfigurera Azure SignalR Service-anslutningssträng antingen i appsettings.json eller med hjälp av verktyget Secret Manager.

Kommentar

Steg 2 kan ersättas med att konfigurera startsammansättningar för värd för användning av SignalR SDK.

  1. Lägg till konfigurationen för att aktivera Azure SignalR Service i appsettings.json:

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string> 
      }
    }
    
    
  2. Konfigurera värdstartssammansättningen så att den använder Azure SignalR SDK. Redigera launchSettings.json och lägg till en konfiguration som i följande exempel i environmentVariables:

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

Har du problem? Berätta för oss.

Rensa resurser

Rensa resurserna som skapats i den här självstudien genom att ta bort resursgruppen via Azure-portalen.

Ytterligare resurser

Nästa steg

I den här självstudiekursen lärde du dig att:

  • Skapa ett enkelt chattrum med Blazor Server-appmallen.
  • Arbeta med Razor-komponenter.
  • Använd händelsehantering och databindning i Razor-komponenter.
  • Snabbdistribution till Azure App Service i Visual Studio.
  • Migrera från lokal SignalR till Azure SignalR Service.

Läs mer om hög tillgänglighet: