Qu'est ce que SignalR?

SignalR, est une librairie de composants qui facilite le développement d'application web temps réel basée sur la communication bidirectionnelle,tel que les chat room dans les sites web, mais aussi le traitement des notifications ou push notification.

SignalR utilise des WebSockets lorsqu'il est possible de se connecter. Ce qui signifie qu'elle supporte tout navigateur compatible avec HTML5.

Un des principaux avantages d'utiliser SignalR est qu'elle supporte des procédures distances appelés (RPCs) avec des applications HTML ou encore .NET et peut

automatiquement basculée sur des versions anciennes de navigateurs pendant une période.

Quels sont ces usages?

SignalR dispose de librairie pour la prise en charge des communications coté serveur, et aussi une librairie javascript pour les traitements des communications coté client.

  • Côté serveur

Pour ajouter la librairie à votre application, vous pouvez utiliser le NuGet pour trouver le package, Microsoft.AspNet.SignalR.

Après installation, vous pouvez implementer du code coté serveur principalement pour ce qui est de la logique côté serveur.

  • Côté client

SignalR aussi inclus une librairie JavaScript qui peut être utilisée pour réaliser des communications entre le serveur et le client. 

SignalR permet de réduire l'effort nécessaire pour le développement d'application temps réel basée sur une communication bidirectionnelle.

Mise en œuvre de la fonctionnalité Push Notification

Comme outil de développement j'utilise Visual Studio 2013

  1. Créer une nouvelle application Web ASP.NET pushNotification.
  2. Choisissez le template Projet Vide 


  1. Après création du projet votre arborescence devrait ressembler à ça


  1. Créer une base de donnée pushNewsDB
AخA
 
1
CREATE DATABASE pushNewsDB;

Créer la table News

9
 
1
CREATE TABLE dbo.News
2
(
3
    NewsID UNIQUEIDENTIFIER,
4
    Content TEXT,
5
    Created DATE,
6
    Modified DATETIME
7
)
8
ALTER TABLE dbo.News
9
ADD CONSTRAINT PK_News PRIMARY KEY (NewsID)

Activer le Service Broker de votre base de données afin de permettre l'envoi et la réception de messages ou conversations entre SQL Server et votre application. Il faut bien comprendre ici qu'il s'agit de messages qui vont transiter via des canaux de communications. Chaque message ou conversation possède un type bien défini. Et ces types peuvent être soit une insertion, une modification, une suppression, une erreur durant l'exécution...

1
 
1
ALTER DATABASE pushNewsDB SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE

Créez le modèle d'entité en utilisant ADO.NET Entity model framework

Créer un nouveau dossier Notifications

Puis ajoutez y  une class SignalR Hub V2

A cet stade le code ci dessous ne fait pas grand chose, il ne fait que

ramener un message hello à tous les clients présent dans le canal de communication

10
 
1
namespace pushNotification.Notifications
2
{
3
    public class NotificationHub : Hub
4
    {
5
        public void Hello()
6
        {
7
            Clients.All.hello();
8
        }
9
    }
10
}

Remplacer le par le code qui se trouve 

x
 
1
[HubName("notificationHub")]
2
    public class NotificationHub : Hub
3
    {
4
        [HubMethodName("sendNotifications")]
5
        public void SendNotifications()
6
        {
7
            string connstr = ConfigurationManager.ConnectionStrings["pushCnstring"].ConnectionString;
8
            using (SqlConnection conn = new SqlConnection(connstr))
9
            {
10
                conn.Open();
11
                string query = "SELECT [NewsID], [Content], [Created], [Modified] FROM [dbo].[News] WHERE [Created] = @CurrentDate";
12
13
                using (SqlCommand cmd = new SqlCommand(query, conn))
14
                {
15
                    try
16
                    {
17
                        cmd.Notification = null;
18
                        DataTable dtbl = new DataTable();
19
                        cmd.Parameters.AddWithValue("@CurrentDate", DateTime.UtcNow.Date);
20
                        SqlDependency sqlDep = new SqlDependency(cmd);
21
                        sqlDep.OnChange += new OnChangeEventHandler(sqlDep_OnChange);
22
23
                        if (conn.State == System.Data.ConnectionState.Closed)
24
                        {
25
                            conn.Open();
26
                        }
27
                        var reader = cmd.ExecuteReader();
28
                        dtbl.Load(reader);
29
                        List<News> listnews = new List<News>();
30
                        if (dtbl.Rows.Count > 0)
31
                        {
32
                            foreach (DataRow dt in dtbl.Rows)
33
                            {
34
                                Guid Id = Guid.Parse(dt["NewsID"].ToString());
35
                                DateTime Created = DateTime.Parse(dt["Created"].ToString());
36
                                DateTime Modified = DateTime.Parse(dt["Modified"].ToString());
37
38
                                string Post = dt["Content"].ToString();
39
40
                                listnews.Add(new News()
41
                                {
42
                                    NewsID = Id,
43
                                    Content = Post,
44
                                    Created = Created,
45
                                    Modified = Modified
46
47
                                });
48
                            }
49
                        }
50
                        conn.Close();
51
52
                        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
53
                        context.Clients.All.RecieveNotification(listnews);
54
55
                    }
56
                    catch (Exception)
57
                    {
58
                        throw;
59
                    }
60
                }
61
62
            }
63
64
        }
65
    }

Expliquons ce que fait concrètement ces instructions

Notre application web doit afficher les dernières actualités du jour. Une requête SQL est donc exécutée afin de récupérer les actualités du jour.

SQLDependency permet d'accéder aux différents changements de la base de données  et de ramener les messages ou conversations entre SQL Server et l'application sous forme de notification en utilisant SQLNotification.  SQLNotification permet d'accéder au type de message ou de la conversation. Soit  Insert, Update, Invalid...


8
 
1
void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
2
{
3
  if (e.Info == SqlNotificationInfo.Insert)
4
  {
5
    NotificationHub nHub = new NotificationHub();
6
    nHub.SendNotifications();
7
  }
8
}

Après on stocke les données de la requête dans une Liste d'objest News, listnews. Puis nous créons un canal de diffusion  des données.

2
 
1
IHubContext context = GlobalHost.ConnectionManager.GetHubContext();
2
context.Clients.All.RecieveNotification(listnews);

Contrôleur

Ajouter maintenant un nouveau Contrôleur Home et  créer une vue Index, pour l'action Index du contrôleur

Laissez le tel qu'il est.

Allez dans le Dossier Shared et ouvrez la vue partielle Layout. 

Ajoutez ce code dans une fonction javascript de démarrage: $(function(){ --code ici--})  Nous avons ajouté le code pour appeler les méthodes du centre de notification et récupérer les données. Les données envoyées par le serveur sont contenues dans data. Vous pouvez donc les manipuler et les afficher.

10
 
1
//Notification
2
var notifications = $.connection.notificationHub;
3
// Create a function that the hub can call to broadcast messages.
4
notifications.client.recieveNotification = function (data) {
5
}
6
$.connection.hub.start().done(function () {
7
notifications.server.sendNotifications();
8
}).fail(function (e) {
9
alert(e);
10
});

Global.asax

Modifiez le fichier Global afin d'assurer la prise en charge des traitements de la base de données par SQLDependency.

17
 
1
public class MvcApplication : System.Web.HttpApplication
2
{
3
 String pushCnstring = ConfigurationManager.ConnectionStrings["pushCnstring"].ConnectionString();
4
 protected void Application_Start()
5
 {
6
  AreaRegistration.RegisterAllAreas();
7
  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
8
  RouteConfig.RegisterRoutes(RouteTable.Routes);
9
  BundleConfig.RegisterBundles(BundleTable.Bundles);
10
  //Start sqldependency
11
  SqlDependency.Start(pushCnstring);
12
 }
13
 protected void Application_End()
14
 {
15
  SqlDependency.Stop(pushCnstring);
16
 }
17
}

Ajoutez la class Startup afin de démarrer le service de Notification au lancement de votre application


Puis modifier là comme suit:

10
 
1
public void SetupPushNotification()
2
{
3
 GlobalHost.DependencyResolver.UseSqlServer(ConfigurationManager.ConnectionStrings["pushCnstring"].ConnectionString);
4
}
5
public void Configuration(IAppBuilder app)
6
{
7
  ConfigureAuth(app);
8
  SetupPushNotification();
9
  app.MapSignalR();
10
}

Créer un nouveau Contrôleur News. Procédez comme précédemment avec le contrôleur Home