ASP.NET SignalR è una libreria open source che ci consente, con estrema semplicità, di aggiungere notifiche real time a una nostra applicazione, instaurando un canale di comunicazione bidirezionale e permanente tra server e client, così che possiamo utilizzarlo per inviare messaggi in entrambi i versi.
Come sappiamo, le specifiche di HTML5 hanno introdotto i WebSocket proprio per soddisfare questa specifica necessità; seppur supportati nativamente da ASP.NET 4.5 e dalle ultime versioni dei più diffusi browser, purtroppo richiedono la presenza di IIS 8 come server web e, specie se stiamo realizzando un sito destinato a un pubblico eterogeneo, non possiamo avere l'assoluta certezza che tutti i nostri visitatori siano compliant con questa tecnologia.
Esistono tuttavia altre tecniche per instaurare una canale di comunicazione full duplex, e il grande pregio di ASP.NET SignalR è proprio quello di astrarre questa problematica, impostando di volta in volta in automatico la connessione più idonea in base alle peculiarità del server e del client. Noi, come sviluppatori, non dobbiamo assolutamente preoccuparci di questi aspetti tecnici, e possiamo concentrarci sulle problematiche di business del prodotto che vogliamo realizzare.
Il nostro primo progetto
Immaginiamo di voler realizzare una semplice chat. Il primo passo è quello di aggiungere al progetto un nuovo oggetto di tipo SignalR Hub Class. Questa operazione include automaticamente i package NuGet necessari ad ASP.NET SignalR.
L'Hub è l'oggetto principale che utilizzeremo per interagire con i client: espone una serie di metodi che possono essere invocati da remoto (per esempio da un client JavaScript) e delle primitive tramite cui inviare dei messaggi a nostra volta. Il nostro ChatHub, nella fattispecie, contiene un metodo SendMessage tramite cui i client possono inviare un messaggio:
public class ChatHub : Hub { public void SendMessage(string message) { Clients.All.newMessage(message); } }
Questo metodo, a sua volta, deve girare il testo ricevuto a tutti i componenti della chat e, per farlo, può sfruttare la proprietà Clients; quest'oggetto è un HubConnectionContext, ossia il gateway tramite cui possiamo inviare messaggi dal server. Nel nostro caso specifico, abbiamo sfruttato la proprietà All, che rappresenta l'insieme di tutti i client collegati all'hub stesso, ma sono disponibili numerose altre modalità per individuare puntalmente i nostri destinatari:
- All, come detto, individua tutti i client connessi;
- Caller rappresenta il client chiamante;
- Client invia un messaggio a un client dato il suo ConnectionID;
- AllExcept invia un messaggio a tutti i client tranne che a quello specificato;
- Others invia un messaggio a tutti i client, tranne che al chiamante;
- Group e OtherInGroup individuano i destinatari in base ai gruppi; si tratta di una funzionalità di cui parleremo approfonditamente in un prossimo script.
Per esempio, se vogliamo inviare un messaggio a tutti i destinatari tranne che al chiamante, potremmo usare la proprietà Others o il metodo AllExcept, come nel codice seguente:
public void SendMessage(string message) { // equivalente a //this.Clients.Others.newMessage(message); this.Clients.AllExcept(this.Context.ConnectionId).newMessage(message); }
L'ultimo passo, prima di poter sfruttare il nostro hub, è quello di aggiungere le impostazioni di routing nella classe RouteConfig:
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { RouteTable.Routes.MapHubs(); routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // altre route... } }
Questa istruzione aggiunge una route che, per default, risponde all'indirizzo ~/signalr/[nomeHub] e che costituisce un proxy JavaScript verso le funzionalità esposte dal nostro hub.
Il codice client side
A questo punto siamo pronti per realizzare il nostro primo client per ASP.NET SignalR, ossia una pagina (per esempio una view di un controller) che contenga i controlli di input necessari per l'inserimento del testo e il codice JavaScript per l'invio, oltre a un div da popolare con i messaggi ricevuti.<div id="container"> <input type="text" id="theMessage" /> <input type="button" value="Send" id="btnSend" /> </div> <div id="chatMessages"></div>
Lo script client di ASP.NET SignalR è contenuto nel package NuGet Microsoft.AspNet.SignalR.JS e va aggiunto tra i riferimenti in pagina unitamente a quello generato dal nostro hub di cui abbiamo parlato poc'anzi. Il contenuto della sezione scripts è simile a quello in basso:
@section scripts { <script src="~/Scripts/jquery.signalR-1.0.1.js" type="text/javascript"></script> <script src="~/signalr/hubs" type="text/javascript"></script> <script type="text/javascript"> $(function () { // Invio messaggi $('#btnSend').click(function () { var text = $('#theMessage').val(); if (text) { $.connection.chatHub.server.sendMessage(text); } }); // Ricezione messaggi $.connection.chatHub.client.newMessage = function (message) { $("#chatMessages").append($('<p>' + message + '</p>')); }; // Attivazione della connessione $.connection.hub.start(); }); </script> }
L'interazione con l'hub server side è estremamente semplice e si basa sull'oggetto chatHub definito nel proxy e, in particolare, sui suoi field client e server: per inviare un messaggio, al click su btnSend, possiamo sfruttare la funzione server.sendMessage; la ricezione, invece, viene gestita associando una funzione di callback a newMessage, che nel nostro caso si occupa di accodare al div chatMessages il testo ricevuto.
Prima di poter procedere con l'invio, però, è necessario invocare la funzione hub.start, che si preoccuperà di negoziare con il server l'attivazione della connessione e di selezionare il protocollo di comunicazione più opportuno. Per esempio, se abbiamo a disposizione Windows 8 e IIS 8, visitando la pagina con Chrome, Firefox o Internet Explorer 10, ASP.NET SignalR sfrutterà WebSocket. Viceversa, su Internet Explorer 8 verrà utilizzato Forever Frame.
Per approfondimenti
Il nostro speciale Web Real Timehttps://www.aspitalia.com/focuson/1300/Speciale-Web-Real-Time-WebSockets-SignalR.aspx
Comunicazione bidirezionale con WebSockets e HTML5
https://www.html5italia.com/script/68/Comunicazione-Bidirezionale-WebSockets-HTML5.aspx
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Inference di dati strutturati da testo con Semantic Kernel e ASP.NET Core Web API
Utilizzare i primary constructor in C#
Cancellare una run di un workflow di GitHub
Come migrare da una form non tipizzata a una form tipizzata in Angular
Usare un KeyedService di default in ASP.NET Core 8
Implementare l'infinite scroll con QuickGrid in Blazor Server
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Miglioramenti nell'accessibilità con Angular CDK
Potenziare Azure AI Search con la ricerca vettoriale
Eseguire una query su SQL Azure tramite un workflow di GitHub
Generare la software bill of material (SBOM) in GitHub
Utilizzare politiche di resiliency con Azure Container App