I. Pourquoi « SignalR » ?▲
« SignalR » est une bibliothèque client/serveur intégrée fournissant toute la plomberie nécessaire pour ajouter des fonctionnalités temps-réel à une application Web ASP.NET.
Cette bibliothèque se base sur les Websockets. Quand ces derniers ne sont pas gérés par le navigateur du client, la librairie offre une solution de fallback en utilisant d'autres techniques sans avoir à changer le code de l'application côté client et serveur. « SignalR » va, en effet, masquer toute la complexité liée à la gestion des appels JavaScript au serveur. Elle va également permettre l'appel de fonctions JavaScript clients à partir du serveur.
Découvrons quelques fonctionnalités de « SignalR » avec un scénario tout simple : notifier les clients connectés sur le site en temps réel à partir d'une interface d'administration.
On va tout d'abord commencer par créer un nouveau projet « ASP.NET MVC4 » vide et après récupérer « SignalR » via « Nuget ».
En utilisant la console du gestionnaire d'extension, « Nuget » lance la commande :
Install-package Microsoft.AspNet.SignalR -pre
Cette dernière va faire le nécessaire pour récupérer toutes les dépendances dont on aura besoin pour pouvoir utiliser « SignalR » dans le projet.
Notez l'utilisation du paramètre « -pre ». « SignalR » est, à la date d'écriture de cet article, en version « release candidate ».
II. Création d'un Hub▲
Un Hub est une classe de l'API « SignalR » côté serveur. Elle va se charger de gérer des appels clients vers le serveur et inversement. Dans notre exemple, nous allons créer un Hub où nous définissons la méthode que l'administrateur doit appeler pour notifier tous les clients connectés sur le site.
Regardons de plus près la classe Notifier :
2.
3.
4.
5.
6.
7.
public
class
Notifier :
Hub
{
public
void
NotifyAllUsers
(
Notification message)
{
Clients.
All.
Broadcast
(
message);
}
}
Rien de bien compliqué. Cette classe hérite de Hub et définit une méthode publique NotifyAllUsers. En définissant cette méthode, nous indiquons à « SignalR » que cette méthode pourra être invoquée par le client. La propriété Clients est héritée de Hub. Elle encapsule des informations concernant les connexions « SignalR ». All, comme son nom l'indique, représente toutes connexions clientes. La méthode Broadcast va invoquer à partir du serveur la fonction du même nom côté client avec le paramètre message.
Pour cet exemple, une notification est une classe très simple :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public
class
Notification
{
// le type de la notification
public
NotificationType Type {
get
;
set
;
}
// en millisecondes, durée pendant laquelle la notification est affichée
public
int
Duration {
get
;
set
;
}
// le texte de la notification
public
string
Text {
get
;
set
;
}
}
public
enum
NotificationType
{
Alert =
0
,
Notice =
1
,
Greeting =
2
,
HotNews =
3
}
Tout aspect lié à la sérialisation/désérialisation de l'objet représentant le message est géré par « SignalR ».
Notez que la property All de Clients est de type dynamic :
En définissant ce Hub côté serveur, « SignalR » va se charger, lors du démarrage de l'application, de générer un proxy en JavaScript contenant toute la mécanique nécessaire pour assurer l'interaction client/serveur avec ce Hub.
Définissons maintenant les vues administrateur et utilisateur.
III. Vue administrateur▲
Afin de simplifier l'exemple, tous les aspects liés à la création du contrôleur et à l'authentification de l'administrateur n'ont pas été traités dans cet article.
Commençons par créer une vue pour la page d'administration :
Dans la vue administrateur, nous allons définir les éléments nécessaires nous permettant d'invoquer la méthode NotifyAllUsers du Notifier Hub.
Tout passe par JavaScript ! Rien de bien compliqué, il suffit de référencer ces scripts dans la vue :
2.
3.
<script type
=
"text/javascript"
src
=
"~/scripts/jquery-1.6.4.min.js"
></script>
<script type
=
"text/javascript"
src
=
"~/scripts/jquery.signalR-1.0.0-rc2.min.js"
></script>
<script type
=
"text/javascript"
src
=
"~/signalr/hubs"
></script>
Notez l'importation de ce script ~/signalr/hubs. À aucun moment on ne l'a défini ou ajouté dans le projet. Ce script contient, en effet, tous les proxys JavaScript des Hubs créés côté serveur. Comme mentionné plus tôt dans l'article, « SignalR » va se charger de la création des proxys et de ce script pour nous.
Et enfin, Voici le script qui va nous permettre d'appeler la méthode NotifyAllUsers du Hub :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
<script type
=
"text/javascript"
>
$(function () {
// proxy correspondant au Hub Notifier défini côté serveur
var notifier = $.connection.notifier
// /!\ Important: Démarrer toutes les connexions aux Hubs
// définis côté serveur
$.connection.hub.start().done(function () {
$('#send').click(function () {
// Construction de la notification en Json
var notification =
{
Text: "Hello world",
Duration: 5000,
Type: 2
};
// invocation de la méthode NotifiyAllUsers
// définie dans le Hub Notifier
notifier.server.notifyAllUsers(notification);
});
});
});
</script>
$.connection.notifier fait référence au Hub créé côté serveur. En effet, si vous regardez le contenu de /signalr/hub, vous allez trouver un JavaScript. Ce script a été généré dynamiquement par « SignalR » à partir du ou des Hubs créés côté serveur.
Le format « Json » est utilisé pour définir une notification.
IV. Vue utilisateur▲
Pour afficher les notifications destinées à tous les utilisateurs du site, il est plus logique de voir apparaître les notifications sur toutes les pages. Je vous recommande d'écrire le JavaScript destiné aux pages utilisateurs dans le « Layout » (si vous utilisez Razor comme view engine) des vues utilisateur (Master page si vous avez opté pour le view engine classique aspx).
Revoyons ce que nous avons défini dans notre Hub.
Clients.
All.
Broadcast
(
message);
Afin de publier le message à tous les clients connectés, nous devons déclarer côté client JavaScript la méthode que le serveur va invoquer :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
<script src
=
"~/scripts/jquery-1.6.4.min.js"
></script>
<script src
=
"~/scripts/jquery.signalR-1.0.0-rc2.min.js"
></script>
<script src
=
"~/signalr/hubs"
></script>
<script>
$(
function
(
) {
// proxy correspondant au Hub Notifier défini côté serveur
var
notifier =
$.
connection.
notifier;
// Déclaration de la fonction que le serveur pourra invoquer
notifier.
client.
broadcast =
function
(
message) {
$(
"
#text
"
).html
(
message.
Text
);
// mettre à jour le contenu du bloc destiné à afficher le message
$(
'
#notification
'
).show
(
1000) // afficher la notification
.delay
(
message.
Duration) // durée spécifiée dans le message envoyé
.hide
(
1000);
// cacher le message après 'message.Duration' millisecondes
};
// Important : démarrer toutes les connexions aux Hubs
// déclarés côté serveur
$.
connection.
hub.start
(
);
}
);
</script>
<div id
=
"notification"
class
=
"notificationStyle"
>
<div id
=
"text"
></div>
</div>
<style>
.notificationStyle
{
background:
#e9e9e9
;
width:
250
px;
border-style:
solid
;
border-width:
2
px;
border-color:
#e1e1e1
;
height:
100
px;
overflow:
hidden
;
box-shadow:
0
px 0
px 10
px 0
px #656565
;
display:
none
;
}
</style>
V. Définition de la route pour le Hub▲
Une route doit être définie pour le ou les Hubs créés. Il nous faudra la définir dans la méthode Application_Start du Global.asax. Cela va permettre d'enregistrer la route ~/signalr.
2.
3.
4.
5.
6.
7.
8.
9.
10.
protected
void
Application_Start
(
)
{
AreaRegistration.
RegisterAllAreas
(
);
// Définition de la route par défaut
RouteTable.
Routes.
MapHubs
(
);
WebApiConfig.
Register
(
GlobalConfiguration.
Configuration);
FilterConfig.
RegisterGlobalFilters
(
GlobalFilters.
Filters);
RouteConfig.
RegisterRoutes
(
RouteTable.
Routes);
BundleConfig.
RegisterBundles
(
BundleTable.
Bundles);
}
Vous pouvez, bien entendu, choisir un autre nom pour la route. Il ne faudra pas dans ce cas oublier de renommer les références vers le script /signalr/hub avec le nom que vous aurez choisi.
VI. Pour aller plus loin▲
Comme vous avez pu le constater, mettre en place une application « ASP.NET MVC » avec des fonctionnalités push “temps réel” est facile avec « SignalR ». Les codes côté client et serveur se retrouvent réduits.
« SignalR » offre d'autres fonctionnalités intéressantes, que je n'ai pas abordées dans cet article, telles que : la prise en charge de groupes de clients, la détection des connexions et déconnexions des clients et la gestion des autorisations.
J'invite les plus curieux d'entre vous à regarder de plus près cette API !
Vous trouverez ici le code de cet article.
VII. Remerciements▲
L'équipe de la rédaction .NET remercie sincèrement Soat de nous avoir autorisés à publier cet article sur Developpez.com. Soat est une société de conseil spécialisée dans l'accompagnement de ses clients, tout au long du cycle de vie de leurs projets et le développement de technologies Java et Web.
Nous remercions également Vincent VIALE pour la mise au gabarit et Malick SECK pour sa relecture orthographique.
N'hésitez pas à donner vos avis sur ce tutoriel sur le forum : 1 commentaire