ASP.NET Core SignalR è probabilmente una della librerie più popolari nell'ecosistema di ASP.NET Core, visto che consente con grande semplicità di rendere interattive le nostre applicazioni, permettendo al server di inviare messaggi ai client connessi grazie al protocollo WebSockets.
Blazor WebAssembly si integra pienamente con SignalR, così che possiamo connetterci al server e implementare le nostre logiche interamente in C#. Vediamo come.
Creazione dell'Hub lato server
Immaginiamo di avere un'applicazione ASP.NET Core che esponga un semplice Hub, come quello in basso, che permette di ricevere un messaggio e girarlo a tutti i client collegati:
internal class MyHub : Hub { public async Task SendMessageAsync(string message) { await this.Clients.All.SendAsync("messageReceived", message); } }
Un Hub del genere può essere associato a un URL nel metodo Configure della classe Startup:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // altro codice qui... app.UseEndpoints(endpoints => { ... endpoints.MapHub<MyHub>("/hubs/myhub"); }); }
Connessione lato client da Blazor WebAssembly
Per sfruttarlo il nuovo Hub da Blazor, come prima cosa dobbiamo aggiungere il package NuGet Microsoft.AspNetCore.SignalR.Client:
dotnet add package Microsoft.AspNetCore.SignalR.Client
A questo punto, possiamo creare una connessione direttamente da un nostro componente, come nell'esempio in basso:
@page "/" @inject NavigationManager Navigation @implements IAsyncDisposable @using Microsoft.AspNetCore.SignalR.Client @* .... altro codice qui .... *@ @code{ private HubConnection _hubConnection; private List<string> _receivedMessages = new List<string>(); protected override async Task OnInitializedAsync() { base.OnInitialized(); _hubConnection = new HubConnectionBuilder() .WithUrl($"{this.Navigation.BaseUri}hubs/myhub") .Build(); _hubConnection.On<string>("messageReceived", message => { _receivedMessages.Add(message); this.StateHasChanged(); }); await _hubConnection.StartAsync(); } public ValueTask DisposeAsync() { return _hubConnection.DisposeAsync(); } }
All'interno del metodo OnInitializedAsync, creiamo una HubConnection che punti all'URL dell'Hub sul server.
Nel nostro caso, stiamo utilizzando un'applicazione Blazor in hosting sullo stesso sito ASP.NET Core che espone l'Hub, per cui abbiamo recuperato l'indirizzo assoluto tramite il BaseUri di NavigationManager. Ovviamente i concetti rimangono assolutamente gli stessi anche nel caso in cui l'Hub risieda su una API esterna, a patto di avere la corretta configurazione di CORS.
Successivamente agganciamo un handler all'evento messageReceived, per aggiungere il nuovo messaggio ricevuto a una collection di _messages e invalidare lo stato del componente, forzandone un nuovo rendering, con una chiamata a StateHasChanged.
Come ultimo passo abbiamo poi, avviamo la connessione chiamando il metodo StartAsync. Un aspetto di cui dobbiamo tener conto è che essa rimarrà attiva per tutta la durata del ciclo di vita di HubConnection. Implementando l'interfaccia IDisposableAsync sul componente, però, possiamo effettuare il DisposeAsync, così da evitare connection leak.
Inviamo e visualizziamo i messaggi
Ora possiamo finalmente implementare la logica per visualizzare e inviare messaggi. Il markup può essere una semplice lista seguita da una InputBox e un Button:
<div> <ul> @foreach (var message in _receivedMessages) { <li> @message </li> } </ul> </div> <div> <input type="text" @bind="_newMessage" /> <button class="btn btn-primary" @onclick="SendMessageAsync">Send</button> </div>
Il metodo SendMessageAsync invocato al click del button, si occupa di inviare il messaggio all'Hub tramite il codice seguente:
private string _newMessage; private async Task SendMessageAsync() { if (!string.IsNullOrWhiteSpace(_newMessage)) { await _hubConnection.SendAsync("SendMessageAsync", _newMessage); _newMessage = string.Empty; } }
Per verificare se abbiamo svolto tutti i passaggi correttamente, ci basterà avviare l'applicazione in un paio di tab differenti: un messaggio inviato da uno dei due apparirà immediatamente su tutti i client connessi:
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Garantire la provenienza e l'integrità degli artefatti prodotti su GitHub
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Effettuare il refresh dei dati di una QuickGrid di Blazor
Eseguire script pre e post esecuzione di un workflow di GitHub
Recuperare App Service cancellati su Azure
Potenziare Azure AI Search con la ricerca vettoriale
Generare velocemente pagine CRUD in Blazor con QuickGrid
Paginare i risultati con QuickGrid in Blazor
Supportare il sorting di dati tabellari in Blazor con QuickGrid
Estrarre dati randomici da una lista di oggetti in C#
Creazione di componenti personalizzati in React.js con Tailwind CSS
Proteggere le risorse Azure con private link e private endpoints