Tutorial: Criar um aplicativo de bate-papo Blazor Server
Este tutorial mostra como criar e modificar um aplicativo Blazor Server. Sabe como:
- Crie uma sala de chat simples com o modelo de aplicativo Blazor Server.
- Trabalhe com componentes do Razor.
- Use a manipulação de eventos e a vinculação de dados nos componentes do Razor.
- Implantação rápida no Serviço de Aplicativo do Azure no Visual Studio.
- Migre do SignalR local para o Serviço Azure SignalR.
Importante
As cadeias de conexão brutas aparecem neste artigo apenas para fins de demonstração.
Uma cadeia de conexão inclui as informações de autorização necessárias para seu aplicativo acessar o Serviço Azure SignalR. A chave de acesso dentro da cadeia de conexão é semelhante a uma senha de root para o seu serviço. Em ambientes de produção, proteja sempre as 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 a ID do Microsoft Entra e autorizar o acesso com a ID do Microsoft Entra.
Evite distribuir chaves de acesso para outros usuários, codificá-las ou salvá-las em qualquer lugar em texto simples acessível a outras pessoas. Rode as chaves se acreditar que podem ter sido comprometidas.
Pronto para começar?
Pré-requisitos
- Instalar o SDK do .NET Core 3.0 (Versão >= 3.0.100)
- Instalar o Visual Studio 2019 (Versão >= 16.3)
Tem problemas? Deixe-nos saber.
Crie uma sala de chat local no aplicativo Blazor Server
A partir da versão 16.2.0 do Visual Studio 2019, o Serviço SignalR do Azure é incorporado ao processo de publicação do aplicativo Web para tornar o gerenciamento das dependências entre o aplicativo Web e o serviço SignalR muito mais conveniente. Você pode trabalhar sem alterações de código ao mesmo tempo:
- em uma instância local do SignalR, em um ambiente de desenvolvimento local.
- no Serviço Azure SignalR para o Serviço de Aplicativo do Azure.
Crie um aplicativo de bate-papo Blazor:
No Visual Studio, escolha Criar um novo projeto.
Selecione Blazor App.
Nomeie o aplicativo e escolha uma pasta.
Selecione o modelo Blazor Server App .
Nota
Verifique se você já instalou o .NET Core SDK 3.0+ para permitir que o Visual Studio reconheça corretamente a estrutura de destino.
Você também pode criar um projeto executando o
dotnet new
comando na CLI do .NET:dotnet new blazorserver -o BlazorChat
Adicione um novo arquivo C# chamado
BlazorChatSampleHub.cs
e crie uma nova classeBlazorChatSampleHub
derivada daHub
classe para o aplicativo de chat. Para obter mais informações sobre como criar hubs, consulte 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 no
Startup.Configure()
método.app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl); });
Instale o
Microsoft.AspNetCore.SignalR.Client
pacote para usar o cliente 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
sob aPages
pasta. Use o arquivo ChatRoom.razor ou execute as seguintes etapas:Adicione a
@page
diretiva e as instruções de uso. Use a@inject
diretiva para injetar oNavigationManager
serviço.@page "/chatroom" @inject NavigationManager navigationManager @using Microsoft.AspNetCore.SignalR.Client;
@code
Na seção , adicione os seguintes membros ao novo cliente 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 da interface do usuário antes da
@code
seção para interagir com o cliente 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
NavMenu.razor
componente para inserir um novoNavLink
componente para vincular à 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
site.css
arquivo para definir o estilo dos elementos da 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ê pode iniciar o bate-papo:
Tem problemas? Deixe-nos saber.
Publicar no Azure
Quando você implanta o aplicativo Blazor no Serviço de Aplicativo do Azure, recomendamos que você use o Serviço Azure SignalR. O Serviço SignalR do Azure permite dimensionar um aplicativo Blazor Server para um grande número de conexões SignalR simultâneas. Além disso, o alcance global e os datacenters de alto desempenho do serviço SignalR ajudam significativamente na redução da latência devido à geografia.
Importante
Em um aplicativo Blazor Server, os estados da interface do usuário são mantidos no lado do servidor, o que significa que uma sessão de servidor adesiva é necessária para preservar o estado. Se houver um único servidor de aplicativo, as sessões adesivas são garantidas por design. No entanto, se vários servidores de aplicativo 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 de estado de interface do usuário inconsistente em um aplicativo Blazor. Portanto, recomenda-se habilitar sessões de servidor adesivas como mostrado em appsettings.json:
"Azure:SignalR:ServerStickyMode": "Required"
Clique com o botão direito do mouse no projeto e vá para Publicar. Utilize as seguintes definições:
- Destino: Azure
- Destino específico: todos os tipos de Serviço de Aplicativo do Azure são suportados.
- Serviço de Aplicativo: crie ou selecione a instância do Serviço de Aplicativo.
Adicione a dependência do Serviço Azure SignalR.
Após a criação do perfil de publicação, você pode ver uma mensagem de recomendação para adicionar o serviço Azure SignalR em Dependências de Serviço. Selecione Configurar para criar um novo ou selecionar um Serviço Azure SignalR existente no painel.
A dependência de serviço executa as seguintes atividades para permitir que seu aplicativo alterne automaticamente para o Serviço Azure SignalR quando estiver no Azure:
- Atualize
HostingStartupAssembly
para usar o Serviço Azure SignalR. - Adicione a referência do pacote NuGet do Serviço Azure SignalR.
- Atualize as propriedades do perfil para salvar as configurações de dependência.
- Configure o armazenamento de segredos de acordo com sua escolha.
- Adicione a configuração no appsettings.json para fazer com que seu aplicativo tenha como destino o Serviço Azure SignalR.
- Atualize
Publicar a aplicação.
Agora o aplicativo está pronto para ser publicado. Após a conclusão do processo de publicação, o aplicativo é iniciado automaticamente em um navegador.
Nota
O aplicativo pode exigir algum tempo para iniciar devido à latência de início da implantação do Serviço de Aplicativo do Azure. Você pode usar as ferramentas de depurador do navegador (geralmente pressionando F12) para garantir que o tráfego foi redirecionado para o Serviço Azure SignalR.
Tem problemas? Deixe-nos saber.
Habilitar o Serviço Azure SignalR para 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 a
AddAzureSignalR()
inStartup.ConfigureServices()
como mostrado no exemplo a seguir:public void ConfigureServices(IServiceCollection services) { ... services.AddSignalR().AddAzureSignalR(); ... }
Configure a cadeia de conexão do Serviço Azure SignalR no appsettings.json ou usando a ferramenta Gerenciador Secreto.
Nota
A etapa 2 pode ser substituída pela configuração de assemblies de inicialização de hospedagem para usar o SDK do SignalR.
Adicione a configuração para ativar o Serviço 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, proteja sempre as 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 a ID do Microsoft Entra e autorizar o acesso com a ID do Microsoft Entra.
"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 exemplo a seguir dentro :
environmentVariables
"environmentVariables": { ..., "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.Azure.SignalR" }
Tem problemas? Deixe-nos saber.
Clean up resources (Limpar recursos)
Para limpar os recursos criados neste tutorial, elimine o grupo de recursos no portal do Azure.
Recursos adicionais
Próximos passos
Neste tutorial, ficou a saber como:
- Crie uma sala de chat simples com o modelo de aplicativo Blazor Server.
- Trabalhe com componentes do Razor.
- Use a manipulação de eventos e a vinculação de dados nos componentes do Razor.
- Implantação rápida no Serviço de Aplicativo do Azure no Visual Studio.
- Migre do SignalR local para o Serviço Azure SignalR.
Leia mais sobre alta disponibilidade: