Nel precedente script abbiamo realizzato il nostro primo progetto di messaggistica con ASP.NET SignalR. Grazie all'uso di un Hub, siamo riusciti a scambiare messaggi tra client e server in maniera bidirezionale e in real time. Dopo aver acquisito i concetti basilari, possiamo continuare l'approfondimento degli Hub esaminando la possibilità di organizzare i client in gruppi, così che vengano a crearsi vari canali di comunicazione ben isolati fra di loro.
I gruppi sono molto utili tutte le volte che dobbiamo creare dei compartimenti nel flusso di messaggi che transitano per l'Hub. Se stiamo scrivendo un'applicazione di chat, per esempio, possiamo intendere il gruppo come una delle sue stanze tematiche. In un'applicazione di diagnostica, invece, il gruppo potrebbe rappresentare una diversa fonte di dati real time.
Gestire l'appartenenza ad un gruppo
L'Hub dispone di una proprietà Groups che, con il suo metodo Add ci consente di aggiungere un client ad un gruppo dal nome arbitrario.public void JoinGroup(string groupName) { // fornisco il ConnectionId che identifica il client e il nome del gruppo Groups.Add(Context.ConnectionId, groupName); }
Il client avrà la facoltà di invocare il metodo pubblico che abbiamo chiamato JoinGroup con una linea di codice javascript; visto che ogni client può appartenere simultaneamente a più gruppi, se per esempio vorrà unirsi ai gruppi "Nuoto" e "Scherma" dovrà usare il codice seguente:
$.connection.nomeHub.server.joinGroup("Nuoto"); $.connection.nomeHub.server.joinGroup("Scherma");
Ovviamente possiamo anche gestire le rimozioni. Per far questo, usiamo il metodo Groups.Remove fornendo, ancora una volta, il ConnectionId del client da rimuovere ed il nome del gruppo.
public void LeaveGroup(string groupName) { Groups.Remove(Context.ConnectionId, groupName); }
In caso di disconnessione, invece, il client lascia il gruppo automaticamente e dunque non è necessario invocare il Groups.Remove in maniera esplicita.
E' importante notare che ASP.NET SignalR, internamente, non mantiene l'elenco dei gruppi esistenti o dei client presenti in ciascun gruppo e, pertanto, non solleva nessuna eccezione se cerchiamo di rimuovere un client da un gruppo in cui non era stato precedentemente inserito. Questo è anche il motivo per cui ASP.NET SignalR non ci fornisce metodi per elencare i nomi di tutti i gruppi di cui un ConnectionId è membro o, viceversa, per ottenere tutti i ConnectionId membri di un gruppo.
Mantenere lo stato di client e gruppi, dunque, è un compito facoltativo che viene affidato a noi sviluppatori.
Inviare messaggi ad un gruppo
Usando il metodo Clients.Group, rivolgeremo i nostri messaggi solo ai client che sono membri di un determinato gruppo. All'interno del nostro Hub creiamo un metodo pubblico come il seguente:
public void SendToGroup(string message, string groupName) { //receiveMessage verrà invocato solo sui client appartenenti a groupName Clients.Group(groupName).ReceiveMessage(message); }
Per inviare un messaggio, il client può invocare il metodo SendToGroup con il seguente codice JavaScript:
// Invio un messaggio da recapitare ai client membri del gruppo ?Nuoto? $.connection.nomeHub.server .sendToGroup("Ciao a tutti gli appassionati del nuoto!", "Nuoto");
Il metodo Clients.Group ci consente anche di escludere dalla ricezione alcuni dei client presenti nel gruppo, fornendo l'elenco dei loro ConnectionId.
// receiveMessage NON verrà invocato sui due client // identificati da connectionId1 e connectionId2, anche se membri di groupName Clients.Group(groupName, connectionId1, connectionId2) .ReceiveMessage(message);
A nostra disposizione abbiamo anche il metodo Clients.OthersInGroup che ci offre un modo conveniente per escludere il client chiamante, cioè colui che ha generato il messaggio da recapitare.
// è una scorciatoia per // Clients.Group(groupName, Context.ConnectionId).ReceiveMessage(message) Clients.OthersInGroup(groupName).ReceiveMessage(message);
Conclusioni
Abbiamo visto come, in maniera molto intuitiva, ASP.NET SignalR consenta di organizzare i client in gruppi e di come rivolgere i messaggi a gruppi specifici.Ci siamo anche imbattuti nell'assenza di un meccanismo di mantenimento e persistenza dello stato, di cui dobbiamo esser coscienti per evitare possibili abusi dell'infrastruttura di comunicazione.
Lato server, sarà una nostra responsabilità impedire che i client possano unirsi, senza autorizzazione, ad eventuali gruppi riservati o che possano inviare i propri messaggi a gruppi di cui non sono entrati a far parte.
Per approfondimenti
Il nostro speciale Web Real Timehttps://www.aspitalia.com/focuson/1300/Speciale-Web-Real-Time-WebSockets-SignalR.aspx
Inviare messaggi al client in real time tramite gli Hub di ASP.NET SignalR
https://www.aspitalia.com/script/1122/Inviare-Messaggi-Client-Real-Time-Tramite-Hub-ASP.NET-SignalR.aspx
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Potenziare Azure AI Search con la ricerca vettoriale
Eseguire query manipolando liste di tipi semplici con Entity Framework Core
Semplificare il deployment di siti statici con Azure Static Web App
Paginare i risultati con QuickGrid in Blazor
Personalizzare l'errore del rate limiting middleware in ASP.NET Core
Usare le collection expression per inizializzare una lista di oggetti in C#
Utilizzare la versione generica di EntityTypeConfiguration in Entity Framework Core
Short-circuiting della Pipeline in ASP.NET Core
Utilizzare gli snapshot con Azure File shares
Effettuare il deploy di immagini solo da container registry approvati in Kubernetes
Definire stili a livello di libreria in Angular
I più letti di oggi
- Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
- Utilizzare il trigger SQL con le Azure Function
- Disabilitare automaticamente un workflow di GitHub (parte 2)
- Ottimizzazione dei block template in Angular 17
- Paginare i risultati con QuickGrid in Blazor
- Ed infine anche il calendario :)
- ecco tutte le novità pubblicate sui nostri siti questa settimana: https://aspit.co/wkly buon week-end!