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
Centrare elementi in HTML tramite CSS
Utilizzare Front Door come CDN di contenuti statici
Sviluppo applicazioni x-plat con .NET MAUI
Le novità di Entity Framework (Core) 7
Agenda di #devconf22 del 26/05 quasi al completo! Ce n'è per tutti i gusti: #dotnet, #aspnetcore, #blazor, #terraform, #githubAltre informazioni e iscrizioni su => https://aspit.co/devconf-22
Sopprimere gli errori di concorrenza quando si elimina una entity con Entity Framework 7
Gestire gli errori di caricamento delle immagini
Installazione di una PWA Blazor
Utilizzare i metodi Linq MinBy e MaxBy per semplificare le ricerche degli elementi minimi e massimi in liste di oggetti complessi con LINQ
Monitorare metriche delle risorse Azure con Load Testing
Gestire dati sensibili nella configurazione in ASP.NET Core
Le novità di ASP.NET Core 7 e Blazor
I più letti di oggi
- Ricevere avvisi su metriche dei server Azure Arc
- Effettuare update massivi con Entity Framework Core 7
- Workflow di continuous deployment tramite pull request label in GitHub
- Sottoscrizione agli eventi sul contenitore in JavaScript
- Effettuare l'upload di un file via FTP con la libreria FluentFTP di .NET
- Catturare la telemetria degli eventi di output cache in ASP.NET Core
- .NET Conference Italia 2022 - Milano e Online
- Monitorare i server on-premises con Azure Arc