Esercitazione: Creare un'app di chat Blazor Server
Questa esercitazione illustra come creare e modificare un'app Blazor Server. Scopri come:
- Creare una chat room semplice con il modello di app Blazor Server.
- Usare i componenti Razor.
- Usare la gestione degli eventi e il data binding nei componenti Razor.
- Eseguire rapidamente la distribuzione nel Servizio app di Azure in Visual Studio.
- Eseguire la migrazione da SignalR locale al Servizio Azure SignalR.
Importante
Le stringa di connessione non elaborate vengono visualizzate in questo articolo solo a scopo dimostrativo.
Un stringa di connessione include le informazioni di autorizzazione necessarie per consentire all'applicazione di accedere alle Servizio Azure SignalR. La chiave di accesso all'interno della stringa di connessione è simile a una password radice per il servizio. Negli ambienti di produzione proteggere sempre le chiavi di accesso. Usare Azure Key Vault per gestire e ruotare le chiavi in modo sicuro e proteggere i stringa di connessione usando Microsoft Entra ID e autorizzare l'accesso con Microsoft Entra ID.
Evitare di distribuire le chiavi di accesso ad altri utenti, impostarle come hardcoded o salvarle in un file di testo normale accessibile ad altri. Ruotare le chiavi se si ritiene che siano state compromesse.
Pronti a iniziare?
Prerequisiti
- Installare .NET Core 3.0 SDK (versione >= 3.0.100)
- Installare Visual Studio 2019 (versione >= 16.3)
Creare una chat room locale nell'app Blazor Server
A partire da Visual Studio 2019 versione 16.2.0, il Servizio Azure SignalR è integrato nel processo di pubblicazione delle applicazioni Web per semplificare la gestione delle dipendenze tra l'app Web e il Servizio SignalR. È possibile lavorare senza modifiche al codice contemporaneamente:
- In un'istanza locale di SignalR, in un ambiente di sviluppo locale.
- Nel Servizio Azure SignalR per il Servizio app di Azure.
Creare un'app Blazor di chat:
In Visual Studio scegliere Crea un nuovo progetto.
Selezionare App Blazor.
Assegnare un nome all'applicazione e scegliere una cartella.
Selezionare il modello App Blazor Server.
Nota
Assicurarsi di aver già installato .NET Core SDK 3.0+ per consentire a Visual Studio di riconoscere correttamente il framework di destinazione.
È anche possibile creare un progetto eseguendo il comando
dotnet new
nell'interfaccia della riga di comando di .NET:dotnet new blazorserver -o BlazorChat
Aggiungere un nuovo file C# denominato
BlazorChatSampleHub.cs
e creare una nuova classeBlazorChatSampleHub
derivante dalla classeHub
per l'app di chat. Per altre informazioni sulla creazione di hub, vedere Creare e usare hub.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); } } }
Aggiungere un endpoint per l'hub nel metodo
Startup.Configure()
.app.UseEndpoints(endpoints => { endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); endpoints.MapHub<BlazorChatSampleHub>(BlazorChatSampleHub.HubUrl); });
Installare il pacchetto
Microsoft.AspNetCore.SignalR.Client
per usare il client SignalR.dotnet add package Microsoft.AspNetCore.SignalR.Client --version 3.1.7
Per implementare il client SignalR, creare un nuovo componente Razor denominato
ChatRoom.razor
nella cartellaPages
. Usare il file ChatRoom.razor o seguire questa procedura:Aggiungere la direttiva
@page
e le istruzioni using. Usare la direttiva@inject
per inserire il servizioNavigationManager
.@page "/chatroom" @inject NavigationManager navigationManager @using Microsoft.AspNetCore.SignalR.Client;
Nella sezione
@code
aggiungere i membri seguenti al nuovo client SignalR per inviare e ricevere messaggi.@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"; } }
Aggiungere il markup dell'interfaccia utente prima della sezione
@code
per interagire con il client 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> }
Aggiornare il componente
NavMenu.razor
per inserire un nuovo componenteNavLink
per collegarsi alla chat room inNavMenuCssClass
.<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>
Aggiungere alcune classi CSS al file
site.css
per applicare uno stile agli elementi dell'interfaccia utente nella pagina della 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;*/ }
Per eseguire l'app, premere F5. È ora possibile avviare la chat:
Pubblicare in Azure
Quando si distribuisce l'app Blazor nel Servizio app di Azure, è consigliabile usare il Servizio Azure SignalR. Il Servizio Azure SignalR consente di aumentare le prestazioni di un'app Blazor Server a un numero elevato di connessioni SignalR simultanee. Inoltre, la copertura globale del Servizio SignalR e i data center a prestazioni elevate consentono di ridurre in modo significativo la latenza dovuta alla geografia.
Importante
In un'app Blazor Server gli stati dell'interfaccia utente vengono mantenuti sul lato server, il che significa che è necessaria una sessione server permanente per mantenere lo stato. Se è presente un singolo server app, le sessioni permanenti vengono assicurate dalla progettazione. Tuttavia, se sono in uso più server app, la negoziazione e la connessione client possono essere reindirizzate a server diversi, il che può causare una gestione incoerente dello stato dell'interfaccia utente in un'app Blazor. Di conseguenza, è consigliabile abilitare sessioni server permanenti, come illustrato in appsettings.json:
"Azure:SignalR:ServerStickyMode": "Required"
Fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica. Usare le seguenti impostazioni:
- Destinazione: Azure
- Destinazione specifica: sono supportati tutti i tipi di Servizio app di Azure.
- Servizio app: creare o selezionare l'istanza del Servizio app.
Aggiungere la dipendenza del Servizio Azure SignalR.
Dopo la creazione del profilo di pubblicazione, è possibile visualizzare un messaggio di raccomandazione per aggiungere il Servizio Azure SignalR in Dipendenze del servizio. Selezionare Configura per creare una nuova istanza o selezionare un'istanza esistente del Servizio Azure SignalR nel riquadro.
La dipendenza del servizio esegue le attività seguenti per consentire all'app di passare automaticamente al Servizio Azure SignalR quando è in Azure:
- Aggiornare
HostingStartupAssembly
per usare il servizio Azure SignalR. - Aggiungere il riferimento al pacchetto NuGet del Servizio Azure SignalR.
- Aggiornare le proprietà del profilo per salvare le impostazioni della dipendenza.
- Configurare l'archivio dei segreti in base all'opzione scelta.
- Aggiungere la configurazione in appsettings.json per fare in modo che l'app usi come destinazione il Servizio Azure SignalR.
- Aggiornare
Pubblica l'app.
L'app è ora pronta per la pubblicazione. Al termine del processo di pubblicazione, l'app viene avviata automaticamente in un browser.
Nota
L'avvio dell'app potrebbe richiedere tempo a causa della latenza di avvio della distribuzione del Servizio app di Azure. È possibile usare gli strumenti del debugger del browser (in genere premendo F12) per assicurarsi che il traffico sia stato reindirizzato al Servizio Azure SignalR.
Abilitare il Servizio Azure SignalR per lo sviluppo locale
Aggiungere un riferimento ad Azure SignalR SDK usando il comando seguente.
dotnet add package Microsoft.Azure.SignalR
Aggiungere una chiamata a
AddAzureSignalR()
inStartup.ConfigureServices()
, come illustrato nell'esempio seguente:public void ConfigureServices(IServiceCollection services) { ... services.AddSignalR().AddAzureSignalR(); ... }
Configurare la stringa di connessione del Servizio Azure SignalR in appsettings.json o usando lo strumento Secret Manager.
Nota
Il passaggio 2 può essere sostituito con la configurazione di Assembly di avvio dell'hosting per l'uso di SignalR SDK.
Aggiungere la configurazione per attivare Servizio Azure SignalR in appsettings.json.
Le stringa di connessione non elaborate vengono visualizzate in questo articolo solo a scopo dimostrativo. Negli ambienti di produzione proteggere sempre le chiavi di accesso. Usare Azure Key Vault per gestire e ruotare le chiavi in modo sicuro e proteggere i stringa di connessione usando Microsoft Entra ID e autorizzare l'accesso con Microsoft Entra ID.
"Azure": { "SignalR": { "Enabled": true, "ConnectionString": <your-connection-string> } }
Configurare l'assembly di avvio dell'hosting per l'uso di Azure SignalR SDK. Modificare launchSettings.json e aggiungere una configurazione simile all'esempio seguente all'interno di
environmentVariables
:"environmentVariables": { ..., "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.Azure.SignalR" }
Pulire le risorse
Per pulire le risorse create in questa esercitazione, eliminare il gruppo di risorse usando il portale di Azure.
Risorse aggiuntive
Passaggi successivi
Questa esercitazione ha descritto come:
- Creare una chat room semplice con il modello di app Blazor Server.
- Usare i componenti Razor.
- Usare la gestione degli eventi e il data binding nei componenti Razor.
- Eseguire rapidamente la distribuzione nel Servizio app di Azure in Visual Studio.
- Eseguire la migrazione da SignalR locale al Servizio Azure SignalR.
Leggere altre informazioni sulla disponibilità elevata: