Articoli di programmazione

SignalR in Blazor

Come aggiungere SignalR per la comunicazione bidirezionale in tempo reale, nelle nostre applicazioni Blazor

photo-1517373116369-9bdb8cdc9f62.jpeg
SIgnalR permette in modo semplice di trasmettere notifiche dal server al client. E' una libreria che con il tempo è stata inclusa in Asp.Net Core.
Di seguito voglio elencare la semplice procedura per abilitare un WebAssembly Blazor all'uso di SignalR.

Per prima cosa abilitare SignalR in Startup nell'applicazione server:

services.AddSignalR();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});


A questo punto creare l'Hub SignalR nella cartella Hubs del progetto (se non c'è va creata). Creeremo qui il nostro primo Hub per la nostra Chat di esempio:

public class ChatHub : Hub
{
public async Task SendMessage(string user, string message, string connId = "")
{
//await Groups.AddToGroupAsync(connId, "Users");
await Clients.All.SendAsync("ReceiveMessage", user, message + $" inviato da {connId}");
}
}

// non dimenticare queste using:
// using Microsoft.AspNetCore.SignalR;
// using System.Threading.Tasks;


All'interno del metodo Configure, sempre in StartUp, dovremo mappare il nuovo Hub:

app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chathub"); // ecco il nostro Hub mappato!
endpoints.MapFallbackToFile("index.html");
});


Lato server abbiamo fatto tutto per il momento.
Passiamo al client Blazor WebAssembly.
Referenziamo SignalR Client con NuGet: Micrososft.AspNetCore.SignalR.Client.
Ora predisponiamo una semplice pagina Blazor per per chattare:

@page "/chat"
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager NavigationManager
@implements IDisposable

<h3>Questa pagina usa SignalR direttamente in pagina per chattare</h3>
<div class="form-group">
<label>
User:
<input @bind="userInput" />
</label>
</div>
<div class="form-group">
<label>
Message:
<input @bind="messageInput" size="50" />
</label>
</div>
<button @onclick="Send" disabled="@(!IsConnected)">Send</button>

<hr>

<ul id="messagesList">
@foreach (var message in messages)
{
<li>@message</li>
}
</ul>

@code {
private HubConnection hubConnection;
private List<string> messages = new List<string>();
private string userInput;
private string messageInput;

protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
.Build();

hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
{
var encodedMsg = $"{user}: {message}";
messages.Add(encodedMsg);
StateHasChanged();
});

//hubConnection.Reconnected += OnReconnect;

await hubConnection.StartAsync();
}

Task Send() =>
hubConnection.SendAsync("SendMessage", userInput, messageInput, hubConnection.ConnectionId);

//async Task OnReconnect(string id) =>
// Console.WriteLine("Connected with id:" + id);

public bool IsConnected =>
hubConnection.State == HubConnectionState.Connected;

public void Dispose()
{
_ = hubConnection.DisposeAsync();
}
}


Non resta che provarlo

#csharp #signalR #tips #aspnetcore #netcore