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
- Instalar o .NET Core 3.0 SDK (Versão >= 3.0.100)
- Instalar o Visual Studio 2019 (Versão >= 16.3)
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.
Crie um aplicativo de chat Blazor:
No Visual Studio, escolha Criar um projeto.
Selecione Aplicativo Blazor.
Dê um nome ao aplicativo e escolha uma pasta.
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.
Crie também um projeto executando o comando
dotnet new
na CLI do .NET:dotnet new blazorserver -o BlazorChat
Adicione um novo arquivo C# chamado
BlazorChatSampleHub.cs
e crie uma classeBlazorChatSampleHub
derivada da classeHub
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); } } }
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); });
Instale o pacote
Microsoft.AspNetCore.SignalR.Client
para usar o cliente do SignalR.dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
Para implementar o cliente SignalR, crie um novo Componente Razor chamado
ChatRoom.razor
na pastaPages
. Use o arquivo ChatRoom.razor ou execute as seguintes etapas:Adicione a diretiva
@page
e as instruções using. Use a diretiva@inject
para injetar o serviçoNavigationManager
.@page "/chatroom" @inject NavigationManager navigationManager @using Microsoft.AspNetCore.SignalR.Client;
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"; } }
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> }
Atualize o componente
NavMenu.razor
para inserir um novo componenteNavLink
a ser vinculado à sala de chat emNavMenuCssClass
.<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>
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;*/ }
Para executar o aplicativo, pressione F5. Agora, você poderá iniciar o chat:
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"
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.
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.
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.
- Atualizar
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.
Está com problemas? Queremos saber.
Habilitar o Serviço do Azure SignalR para o desenvolvimento local
Adicione uma referência ao SDK do Azure SignalR usando o comando a seguir.
dotnet add package Microsoft.Azure.SignalR
Adicione uma chamada para
AddAzureSignalR()
emStartup.ConfigureServices()
, conforme mostrado no exemplo a seguir:public void ConfigureServices(IServiceCollection services) { ... services.AddSignalR().AddAzureSignalR(); ... }
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.
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> } }
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: