Gestire i gruppi in un Hub di ASP.NET SignalR

di Moreno Gentili, in ASP.NET 4.5, ASP.NET MVC, SignalR,

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 Time
https://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

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi