Compartilhar via


Tutorial: Criar um aplicativo de chat do Blazor Server

Este tutorial mostra como criar e modificar um aplicativo Blazor Server. Você aprenderá como:

  • Criar uma sala de chat simples com o modelo de aplicativo Blazor Server.
  • Trabalhar com os componentes do Razor.
  • Usar a manipulação de eventos e a associação de dados em componentes do Razor.
  • Implantar rapidamente o Serviço de Aplicativo do Azure no Visual Studio.
  • Fazer a migração do SignalR local para o Serviço do Azure SignalR.

Importante

As cadeias de conexão brutas aparecem neste artigo somente para fins de demonstração.

Uma cadeia de conexão inclui as informações de autorização necessárias para que seu aplicativo acesse o Serviço do Azure SignalR. A chave de acesso dentro da cadeia de conexão é semelhante a uma senha raiz para o serviço. Em ambientes de produção, sempre proteja suas chaves de acesso. Use o Azure Key Vault para gerenciar e rotacionar suas chaves com segurança, proteja sua cadeia de conexão usando o Microsoft Entra ID e autorize o acesso com o Microsoft Entra ID.

Evite distribuir chaves de acesso para outros usuários, fazer hard-coding com elas ou salvá-las em qualquer lugar em texto sem formatação que seja acessível a outras pessoas. Gire suas chaves se você acredita que elas podem ter sido comprometidas.

Pronto para começar?

Pré-requisitos

Está enfrentando problemas? Queremos saber.

Criar uma sala de chat local no aplicativo Blazor Server

No Visual Studio 2019 versão 16.2.0 em diante, o Serviço do Azure SignalR é incorporado ao processo de publicação do aplicativo Web para tornar o gerenciamento das dependências entre o aplicativo Web e o Serviço do SignalR muito mais conveniente. Você pode trabalhar sem nenhuma alteração de código ao mesmo tempo:

  • em uma instância local do SignalR, em um ambiente de desenvolvimento local.
  • no Serviço do Azure SignalR para o Serviço de Aplicativo do Azure.
  1. Crie um aplicativo de chat Blazor:

    1. No Visual Studio, escolha Criar um projeto.

    2. Selecione Aplicativo Blazor.

    3. Dê um nome ao aplicativo e escolha uma pasta.

    4. Selecione o modelo Aplicativo Blazor Server.

      Observação

      Verifique se você já instalou o SDK do .NET Core 3.0 ou posterior a fim de permitir que o Visual Studio reconheça corretamente a estrutura de destino.

      Em Criar um projeto, selecione o modelo de aplicativo Blazor.

    5. Crie também um projeto executando o comando dotnet new na CLI do .NET:

      dotnet new blazorserver -o BlazorChat
      
  2. Adicione um novo arquivo C# chamado BlazorChatSampleHub.cs e crie uma classe BlazorChatSampleHub derivada da classe Hub para o aplicativo de chat. Para obter mais informações sobre como criar hubs, confira Criar e usar 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. Adicione um ponto de extremidade para o hub o método Startup.Configure().

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
        endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl);
    });
    
  4. Instale o pacote Microsoft.AspNetCore.SignalR.Client para usar o cliente do SignalR.

    dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
    
  5. Para implementar o cliente SignalR, crie um novo Componente Razor chamado ChatRoom.razor na pasta Pages. Use o arquivo ChatRoom.razor ou execute as seguintes etapas:

    1. Adicione a diretiva @page e as instruções using. Use a diretiva @inject para injetar o serviço NavigationManager.

      @page "/chatroom"
      @inject NavigationManager navigationManager
      @using Microsoft.AspNetCore.SignalR.Client;
      
    2. Na seção @code, adicione os membros a seguir ao novo cliente do SignalR para enviar e receber mensagens.

      @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. Adicione a marcação de interface do usuário antes da seção @code para interagir com o cliente do 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. Atualize o componente NavMenu.razor para inserir um novo componente NavLink a ser vinculado à sala de chat em 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. Adicione algumas classes CSS ao arquivo site.css para definir o estilo dos elementos de interface do usuário na página de 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. Para executar o aplicativo, pressione F5. Agora, você poderá iniciar o chat:

    Um chat animado entre Bob e Alice é exibido. Alice diz Olá, Bob diz Oi.

Está com problemas? Queremos saber.

Publicar no Azure

Quando você implantar o aplicativo Blazor no Serviço de Aplicativo do Azure, recomendaremos usar o Serviço do Azure SignalR. O Serviço do Azure SignalR permite dimensionar um aplicativo Blazor Server para um grande número de conexões simultâneas do SignalR. Além disso, o alcance global do Serviço do SignalR e os datacenters de alto desempenho ajudam significativamente a reduzir a latência devido à geografia.

Importante

Em um aplicativo Blazor Server, os estados de interface do usuário são mantidos no lado do servidor, o que significa que uma sessão de servidor temporária é necessária para preservar o estado. Se houver um só servidor de aplicativos, as sessões temporárias serão garantidas por design. No entanto, se vários servidores de aplicativos estiverem em uso, a negociação e a conexão do cliente poderão ser redirecionadas para servidores diferentes, o que pode levar a um gerenciamento inconsistente do estado da interface do usuário em um aplicativo Blazor. Portanto, é recomendável habilitar as sessões de servidor fixo, conforme mostrado em appsettings.json:

"Azure:SignalR:ServerStickyMode": "Required"
  1. Clique com o botão direito do mouse no projeto e acesse Publicar. Use as configurações a seguir:

    • Destino: Azure
    • Destino específico: há suporte para todos os tipos de Serviço de Aplicativo do Azure.
    • Serviço de Aplicativo: crie ou selecione a instância do Serviço de Aplicativo.

    A animação mostra a seleção do Azure como destino e, em seguida, o Serviço de Aplicativo do Azure como destino específico.

  2. Adicione a dependência do Serviço do Azure SignalR.

    Após a criação do perfil de publicação, você poderá ver uma mensagem de recomendação para adicionar o Serviço do Azure SignalR em Dependências de Serviço. Escolha Configurar para criar ou selecionar um Serviço do Azure SignalR existente no painel.

    Em Publicar, o link para a opção Configurar é realçado.

    A dependência do serviço executa as seguintes atividades para permitir que seu aplicativo alterne automaticamente para o Serviço do Azure SignalR quando estiver no Azure:

    • Atualizar HostingStartupAssembly para usar o Serviço do Azure SignalR
    • Adicione a referência do pacote NuGet do Serviço do Azure SignalR.
    • Atualize as propriedades do perfil para salvar as configurações de dependência.
    • Configure o repositório de segredos de sua preferência.
    • Adicione a configuração em appsettings.json para fazer com que o aplicativo tenha como destino o Serviço do Azure SignalR.

    Em Resumo das alterações, as caixas de seleção são usadas para selecionar todas as dependências.

  3. Publique o aplicativo.

    Seu aplicativo está pronto para ser publicado. Após a conclusão do processo de publicação, o aplicativo será iniciado automaticamente em um navegador.

    Observação

    O aplicativo pode exigir algum tempo para ser iniciado devido à latência de início da implantação do Serviço de Aplicativo do Azure. Você pode usar as ferramentas do depurador de navegador (normalmente pressionando F12) para garantir que o tráfego tenha sido redirecionado para o Serviço do Azure SignalR.

    O Exemplo de Chat do SignalR do Blazor tem uma caixa de texto para seu nome e um botão Chat! para iniciar um chat.

Está com problemas? Queremos saber.

Habilitar o Serviço do Azure SignalR para o desenvolvimento local

  1. Adicione uma referência ao SDK do Azure SignalR usando o comando a seguir.

    dotnet add package Microsoft.Azure.SignalR
    
  2. Adicione uma chamada para AddAzureSignalR() em Startup.ConfigureServices(), conforme mostrado no exemplo a seguir:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddSignalR().AddAzureSignalR();
        ...
    }
    
  3. Configure a cadeia de conexão do Serviço do Azure SignalR em appsettings.json ou usando a ferramenta Gerenciador de Segredos.

Observação

A etapa 2 pode ser substituída por meio da configuração de Assemblies de Inicialização de Hospedagem para usar o SDK do SignalR.

  1. Adicione a configuração para ativar o Serviço do Azure SignalR no appsettings.json.

    As cadeias de conexão brutas aparecem neste artigo apenas para fins de demonstração. Em ambientes de produção, sempre proteja suas chaves de acesso. Use o Azure Key Vault para gerenciar e girar suas chaves com segurança e proteger sua cadeia de conexão usando o Microsoft Entra ID e autorizar o acesso com o Microsoft Entra ID.

    "Azure": {
      "SignalR": {
        "Enabled": true,
        "ConnectionString": <your-connection-string> 
      }
    }
    
    
  2. Configure o assembly de inicialização de hospedagem para usar o SDK do Azure SignalR. Edite launchSettings.json e adicione uma configuração como o seguinte exemplo dentro de environmentVariables:

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

Está enfrentando problemas? Queremos saber.

Limpar os recursos

Para limpar os recursos criados neste tutorial, exclua o grupo de recursos usando o portal do Azure.

Recursos adicionais

Próximas etapas

Neste tutorial, você aprendeu a:

  • Criar uma sala de chat simples com o modelo de aplicativo Blazor Server.
  • Trabalhar com os componentes do Razor.
  • Usar a manipulação de eventos e a associação de dados em componentes do Razor.
  • Implantar rapidamente o Serviço de Aplicativo do Azure no Visual Studio.
  • Fazer a migração do SignalR local para o Serviço do Azure SignalR.

Leia mais sobre a alta disponibilidade: