Per lavoro ho iniziato a muovere i primi passi con SignalR. SignalR è una libreria che crea una persistent connection tra client e server, permettendo al server di inviare al client dati in modalita push. Crea inoltre un’astrazione sulla modalità di trasporto adottata (periodic polling, long polling & websockets), e fornisce un’unica interfaccia di programmazione.
Ma perche’ utilizzarla? Un’applicazione necessita del real-time perché ci sono situazioni in cui i dati visualizzati devono essere aggiornati costantemente (in modalita push). Un caso emblematico può essere quello delle quotazioni di borsa.
Il web è basato sul protocollo HTTP, che per sua natura è request/response. Pertanto, ci troviamo ad utilizzare un protocollo unidirezionale senza stato (ovvero che non permette di fare delle chiamate push server-to-client in maniera nativa). Per utilizzare una modalità push, quindi, dobbiamo ricorrere ad alcuni workaround. Ci sono molti siti ufficiali, blog, tutorial, etc. per documentarsi. Questo e’ solo il mio primo esempio.
La parte di configurazione ed installazione la lascio al sito microsoft… Il progetto che presentero’ e’ una banale console per visualizzare log in real time da diverse fonti, in questo caso da diverse webApi.
Ci sono 3 livelli di log (lOG4nET): debug, info, error. In SignalR, ogni livello di log è che sia proprio gruppo. L’interfaccia utente consente all’utente di passare ogni livello. Ogni livello di log e’ associato ad un’attivita’ di SignalR. L’implementazione finale e’ semplice: Quando il logger ricerve un messaggio, lo trasmette al gruppo associato. Ogni metodo di log chiama Log(string level, string message):
public void Log(string loglevel, string message) { Log(new LogItem() { Level = loglevel, Message = message }); } private void Log(LogItem item) { IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>(); dynamic clients = connectionManager.GetClients<LogEndpoint>(); clients[item.Level].receiveLogEntry(item); }
L’hub espone 2 metodi: WatchLevel(string) and UnwatchLevel(string) which add the current connection to the group.
public void WatchLevel(string level) { if (LogLevels.Contains(level)) { AddToGroup(level); } } public void UnwatchLevel(string level) { if (LogLevels.Contains(level)) { RemoveFromGroup(level); } }
Il frontend ha un metodo principale chiamato receiveLogEntry che accetta un LogItem come parametro.
LogItem è un semplice POCO con Timstamp, livello, e proprietà del messaggio.
I nuovi messaggi vengono anteposti alla tabella o aggiunti alla console a seconda della vista.
Quanto detto e’ il funzionamento di base.
Nel progetto ho aggiunto un paio di cose come la codifica a colori dei messaggi di errore
e una semplice scroll automatica ed un elenco di connessioni correnti e di
registrazione semplici in tutta l’applicazione.
Questo e’ un semplice punto di partenza per avere un log centralizzato. A questo link e’ possibile fare il download del
progetto github qui.