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 o seu aplicativo acesse o serviço Azure Web PubSub. 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 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.
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: