Un esempio di implementazione di una conversazione di testo in tempo reale con la libreria SignalR
Autore: Denis Balant, Enej Hudobreznik
Il protocollo HTTP (Hypertext Transfer Protocol) viene ancora utilizzato principalmente per la trasmissione di dati su Internet. è il derivato crittografato HTTPS (HTTP Secure) più moderno e più sicuro. Si basano sull'architettura client-server, in cui il client (client inglese) invia una richiesta (richiesta HTTP inglese) al server (server inglese) e il server risponde con una risposta (risposta HTTP inglese).
I protocolli HTTP e HTTPS sono adatti per semplici trasferimenti di richiesta-risposta (ad esempio trasferimento di un file HTML su richiesta del client). Utilizzando questi due protocolli, l'utente può ottenere dati aggiornati solo quando invia una nuova richiesta, quindi non sono i più adatti per il trasferimento di dati in tempo reale (ad esempio chat online, videogiochi online, localizzazione... ), su cui si basa gran parte della funzionalità delle moderne applicazioni web. L’agilità può essere implementata in molti modi diversi e migliori, ciascuno con i propri vantaggi e svantaggi.
Il metodo di implementazione più semplice è il polling regolare, in cui il client invia ripetutamente richieste di nuovi dati al server ad ogni intervallo di polling, indipendentemente dal fatto che il contenuto sia cambiato o meno. Nonostante la sua semplicità, questo approccio non è adatto a servizi più grandi dove l'accesso al server richiede molti client, perché una grande quantità di richieste inutili e ripetute possono sovraccaricarlo e quindi rallentare le prestazioni del servizio.
Il miglioramento si ottiene introducendo il polling a lungo termine, in cui il client invia richieste al server allo stesso modo, ma il server non risponde finché non rileva la presenza di nuovi dati. Lo svantaggio di un simile approccio è che il client deve avere definito un determinato intervallo di tempo dopo il quale riconosce l'inattività del server come un errore. Ciò aggiunge un ulteriore livello di complessità alla configurazione del client e del server.
Il moderno standard HTML5 fornisce anche un'API chiamata Server-Sent Events. È un protocollo in cui il client non deve inviare periodicamente richieste al server, ma il server invia nuovamente i dati necessari quando vengono apportate modifiche, facilitando così la comunicazione in tempo reale.
Lo standard HTML5 offre anche il protocollo WebSockets, che consente una vera comunicazione bidirezionale in tempo reale. All'inizio dell'istituzione, viene eseguito un handshake, in cui il client e il server concordano sull'insieme di standard che utilizzeranno. Dopo una stretta di mano riuscita, tra i due partecipanti viene aperta una connessione permanente con un piccolo ritardo. Questo protocollo è particolarmente utile quando si tratta di una connessione punto a punto (una connessione diretta tra un client e un server).
Oltre alla classica architettura client-server, esistono altre soluzioni in cui la connessione tra client non avviene attraverso server, ma direttamente tra client che svolgono sia il ruolo di client che di server (queste reti peer-to-peer). Un protocollo popolare per la comunicazione in tempo reale in tali reti è WebRTC.
Nell'ambiente .NET per la comunicazione in tempo reale, possiamo utilizzare la libreria open source SignalR, che fa parte del framework web ASP.NET Core, quindi è facile aggiungerla ai progetti esistenti come livello middleware aggiuntivo durante l'elaborazione richieste in arrivo. La libreria simula chiamate al metodo sul client dal lato server e chiamate al metodo sul server dal lato client (Remote Procedure Call - RPC), ma non garantisce la congruità del n. parametri e i loro tipi. Dal server possiamo chiamare metodi su tutti i client, su un gruppo specifico di client o su un solo client.
Il suo principale vantaggio è la semplicità di implementazione grazie ai pacchetti di sviluppo software (SDK) per molte piattaforme diverse, che nascondono il funzionamento interno del servizio ai programmatori, e la possibilità di un facile hosting con il servizio Azure SignalR. Un ulteriore vantaggio è che è il servizio stesso a scegliere il tipo di connessione più appropriato (descritto sopra) tra il client e il server.
L'utilizzo della libreria si basa su classi speciali chiamate hub, che rappresentano un'astrazione della connessione tra client e server. Per loro definiamo i metodi che i client possono chiamare sul server.
L'esempio seguente mostra un esempio di una semplice implementazione di una conversazione di testo. Per prima cosa definiamo il nodo base per la conversazione sul server. I metodi di questa classe rappresentano metodi che possono essere chiamati dai client sul server. Quando viene chiamato il metodo SendMessage, il client invia l'ID utente (userId) e il contenuto del messaggio (message), mentre il server chiama il metodo ReceiveMessage su tutti i client con i parametri specificati.
L'esempio seguente mostra un'implementazione del client Web JavaScript utilizzando la libreria ufficiale (@microsoft/signalr). I client si connettono all'URL del nodo (/chat nell'esempio seguente). Una connessione è rappresentata dall'oggetto connessione. Il metodo on rappresenta un ascoltatore della chiamata al metodo, il cui nome viene fornito come primo parametro e come secondo la funzione che viene eseguita sull'evento. Implementiamo i metodi sul server tramite il metodo invoke dell'oggetto connessione, che richiede come primo argomento il nome del metodo, seguito dai suoi parametri.
Per impostazione predefinita, i dati vengono trasferiti tra il server e i client in formato JSON, ma la libreria supporta anche il formato MessagePack più efficiente.
Sebbene la libreria faciliti notevolmente lo sviluppo, presenta i suoi svantaggi. Uno dei principali è la scalabilità del sistema nel proprio hosting e la garanzia di un funzionamento ininterrotto, poiché la sua implementazione è molto difficile da distribuire su più server separati. Ciò risulta particolarmente difficile se vogliamo ridurre la latenza per gli utenti remoti e ospitare più sedi diverse, poiché la progettazione della soluzione è limitata a una sola. Inoltre, la biblioteca non garantisce la consegna e l'ordinamento affidabili dei messaggi, il che può peggiorare l'esperienza dell'utente.