SignalR non è sicuramente una novità: è stato, infatti, introdotto all’interno di ASP.NET circa cinque anni fa come strumento per la creazione di applicazioni real-time. Nel 2018, con il rilascio di .NET Core 2.1, è stato rilasciato anche all’interno di .NET Core: è quindi disponibile per l’integrazione all’interno di applicazioni cross-platform. SignalR è perfettamente integrato all’interno della suite Azure il servizio SignalR che consente di creare servizi in tempo reale, come ad esempio bot, chat multipiattaforma e dashboard in tempo reale. Inoltre è consigliato in tutte quelle applicazioni che necessitano di update rapidi (con un alto rate di aggiornamento) oppure quando si ha la necessità di implementare la comunicazione full-duplex.
SignalR è una libreria open-source che consente di aggiungere notifiche real-time alle applicazioni web creando un canale bidirezionale tra client (browser) ed server (Web App).
E’ il framework ad ottimizzare il tipo di canale di comunicazione: gli sviluppatori possono dedicarsi allo sviluppo, senza addentrarsi all’interno degli aspetti tecnici della creazione/mantenimento del canale.
Rispetto alla versione precedente (ASP NET SignalR), la versione ASP NET Core presenta alcune differenze:
- non supporta la riconnessione automatica del client nel caso in cui la connessione sia stata interrotta
- supporta JSON e MessagePack (serializzazione binaria che crea dei messaggi più piccoli rispetto al JSON)
- la libreria ASP.NET Core SignalR Client è stata totalmente riscritta in Typescript
- non è più necessario includere la libreria JQuery in quanto sono state tolte tutte le dipendenze
- la libreria client non è più disponibile all’interno di nuget, ma è possibile scaricarla direttamente da npm
- supporto per Azure SignalR Service
- supporto per SignalR scaleout with Redis
Utilizzo
Per poter utilizzare SignalR all’interno di un’applicazione ASP.NET Core è necessario aggiungere:
using Microsoft.AspNetCore.SignalR
In particolare, è contenuto all’interno del package :
Microsoft.AspNetCore.App
Il funzionamento di SignalR è basata su due entità ben distinte:
- Client: una libreria javascript che consente il collegamento dalle View (html) al server
- Server: una o più classi che ereditano da Hub. All’interno di queste classi devono essere definiti i metodi pubblici, ad esempio per l’invio dei messaggi
Semplificando, le classi che eredidano da Hub espongono i metodi public, che possono essere richiamati dai client. Solo i metodo public possono essere richiamati.
Esempio – Realizzazione di una chat
Una volta creata l’appliazione è necessario modificare Startup.cs per abilitare l’utilizzo di SignalR, abilitando all’interno del metodo ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
}
inoltre all’interno del metodo è necessario definire la route che verrà utilizzata dai client:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSignalR(routes =>
{
routes.MapHub<ChatHub>("/chat");
});
}
Nell’esempio precedente la route definita è /chat .
Definiamo quindi la classe che eredita da Hub, all’interno della quale sono definiti i metodi pubblici raggiungibili dai client.
public class ChatHub : Hub
{
public void Send(string name, string message)
{
Clients.All.SendAsync("broadcastMessage", name, message);
}
}
All”interno della cartella /wwwroot possiamo creare una semplice pagina html (anche se la logica può essere ovviamente integrata all’interno di Views/Razor Pages). Per poter utilizzare signalr lato client è necessario includere la libreria (in questo caso in versione minimizzata):
<script type="text/javascript" src="lib/signalr.min.js"></script>
Di seguito il codice completo della pagina html :
<!DOCTYPE html>
<html>
<head>
<title>SignalR Simple Chat</title>
<style type="text/css">
.container {
background-color: #99CCFF;
border: thick solid #808080;
padding: 20px;
margin: 20px;
}
</style>
</head>
<body>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<ul id="discussion"></ul>
</div>
<!--Script references. -->
<!--Reference the SignalR library. -->
<script type="text/javascript" src="lib/signalr.min.js"></script>
<!--Add script to update the page and send messages.-->
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
var messageInput = document.getElementById('message');
// Get the user name and store it to prepend to messages.
var name = prompt('Enter your name:', '');
// Set initial focus to message input box.
messageInput.focus();
// Start the connection.
var connection = new signalR.HubConnectionBuilder()
.withUrl('/chat')
.build();
// Create a function that the hub can call to broadcast messages.
connection.on('broadcastMessage', function (name, message) {
// Html encode display name and message.
var encodedName = name;
var encodedMsg = message;
// Add the message to the page.
var liElement = document.createElement('li');
liElement.innerHTML = '<strong>' + encodedName + '</strong>: ' + encodedMsg;
document.getElementById('discussion').appendChild(liElement);
});
// Transport fallback functionality is now built into start.
connection.start()
.then(function () {
console.log('connection started');
document.getElementById('sendmessage').addEventListener('click', function (event) {
// Call the Send method on the hub.
connection.invoke('send', name, messageInput.value);
// Clear text box and reset focus for next comment.
messageInput.value = '';
messageInput.focus();
event.preventDefault();
});
})
.catch(error => {
console.error(error.message);
});
});
</script>
</body>
</html>
Da notare il codice javascript
connection.on('broadcastMessage'....)
che viene richiamato ogni volta che viene inviato un messaggio dall’HUB del server. Il resto viene gestito come codice javascript tradizionale.
SignalR è sicuramente un modo semplice e facilmente sviluppabile per poter realizzare applicazioni realtime. Oltre all’utilizzo all’interno di applicazioni di chat, è adatto per lo sviluppo di applicazioni che hanno la necessità di aggiornare dati con frequenza elevata, o realizzare applicazioni con comunicazione full-duplex.