SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Mettez du temps réel dans
votre Drupal avec NodeJS
Qui sommes nous ?

  ● Matthieu Guillermin - Multitask
    Consultant chez
      @mguillermin



  ● Nicolas Chambrier - Nodefag Troll
    Développeur chez
       @naholyr
Pourquoi intégrer Drupal / NodeJS ?
● On va de plus en plus vers des architectures
  hétérogènes
● Utiliser chaque techno pour ce qu'elle sait
  bien faire
● Les besoins de "temps-réels" sont de plus
  en plus présents
Le Cas d'Utilisation
Le Cas d'Utilisation
● Notre but était de :
   ○ Utiliser Drupal pour ce qu'il fait de mieux
   ○ Utiliser NodeJS pour ce qu'il fait de mieux
   ○ Trouver un cas d'utilisation réellement utile
● En utilisant des fonctionnalités classiques à
  la fois pour Drupal et pour NodeJS
Le Cas d'Utilisation
● Drupal :
  ○ Gestion de contenu
  ○ Contribution
  ○ Workflow
● NodeJS :
  ○ Mise en place d'une API REST
  ○ Application "temps réel"
Le Cas d'Utilisation
● Système de notification
  ○ Messages affichés directement dans le navigateur
  ○ En réponse à des événements Drupal
  ○ Envoi en "temps-réel"
● Paramétrable
  ○ Définition de règles d'envoi de messages
  ○ Définition des destinataires des message
Comment le réaliser ?
Comment le réaliser ?
● Utilisation de standards Web
● Communication depuis Drupal
  ○ Web Services
  ○ REST
● Communication depuis le client
  ○ Accès direct au serveur NodeJS
Comment le réaliser ?

                Appel Web Service   Serveur
   Drupal
                                    NodeJS



                                        Dispatch &
       Action
                                        Notification



  Navigateur                  Navigateur
                                    Navigateur
    client                      client
                                       client
Mise en oeuvre NodeJS
Comment on a travaillé
● Pas de super-héros !
   ○ Je n'y connais rien à Drupal
   ○ Il n'y connait pas grand chose à Node

● Il faut:
   ○ Savoir installer et faire tourner le travail de l'autre
     ■ Drupal: LAMP + dump MySQL
     ■ Node: NodeJS → `node app.js`

   ○ Définir l'API avant tout
     ■ Sur un coin de table 3 jours avant

   ○ C'est tout !
Un serveur HTTP + WebSocket
● On veut que ce soit simple
  ○ Toute la stack dans une seule application
  ○ Notifier = une requête HTTP simple
  ○ Afficher les notifications = une inclusion de script +
    une ligne de config

● On veut que ce soit sécurisé, performant,
  et scalable
  ○ Oui mais c'est un tout autre sujet ;)
One app to rule them all
                     var app = http.createServer(handler)
Notifications
                     function handler (req, res) {

                         if (req.url === "/" &&
                             req.method === "POST") {
                           newNotification(req, res)
                         }

                         else {
Fichiers statiques         serveStatic(req, res);
                         }
                     }

WebSockets           var io = require('socket.io')

                     io.listen(app)
Modèle de données
● Identifier les paramètres requis:
   ○ On veut un message
     → "message": String

   ○ On veut cibler les utilisateurs par rôle
     → "roles": [String]

   ○ On veut éventuellement cibler par utilisateur
     → "users": [String]

● JSON: {   "roles": ["administrator"], "users": [1],
   "message": "hello, world" }
API REST
                       function newNotification (req, res)
● JSON                 {

                           if (!isJSON(req)) {
● Création = POST            error400()
                           }
● Réponse adaptée:
  201 - Created            var notif = JSON.parse(req.body)
  400 - Bad Request        validateNotif(notif)
  500 - Server Error
                           notif.id = uuid()

● Broadcast via            broadcastViaWebSocket(notif)
  WebSocket
                           respond(res,
                             201, "application/json",
                             JSON.stringify(notif))
                       }
function display (id, roles) {
API Client                 addJS("socket.io.js")
                           addCSS("notifications.css")
● Script servi par         addDOMContainer()
   l'application
                           var socket = io.connect()

● Une seule fonction       socket.on('connect', function ()
                       {
                                socket.emit('roles', roles)
● Ajoute seul les               socket.emit('user_id', id)
   dépendances             })
   JS & CSS                socket.on('error', function (e) {
                              notifyError(e)
                           })
● Enrichit le DOM          socket.on('notif', function (n) {
                              notifyInfo(n)
                           })
● Gère le WebSocket
                       }
API : Utilisation
Client
<script src="http://localhost:8080/notifications.js"
></script>
<script>notifications.display(1, ["administrator"])</script>


Serveur
POST http://localhost:8080
Content-Type: application/json
{"roles":["administrator"],"message":"Show me your big
power"}


Simple enough ?
Socket.IO
● Pourquoi Socket.IO ?
  ○ Puissant, simple, efficace, hyper-compatible.

● Comment distribuer les messages ?
  ○ Filtrer côté client ? Pas efficace
  ○ Côté serveur: comment router les message ?

● Socket.IO à la rescousse: les "rooms":
  ○ Client: socket.join("room")
  ○ Serveur: io.sockets.in("room").emit(data)
  ○ Nos salons: "USER:$id" & "ROLE:$role"

● Problème des notifications en double
Socket.IO - implémentation
● Client         socket.on('connect', function () {
                   socket.emit('user_id', user_id);
                 });


                 socket.on('user_id', function (user_id)
● Serveur        {
                   socket.join('USER:' + user_id);
                 });


                 notification.users.forEach(function (id)
                 {
● Notification     io.sockets
                   .in('USER:' + id)
                   .emit('notification', notification);
                 });
Résultat   [WARNING: PROTOTYPE]

      naholyr/node-drupal-notifications
Mise en oeuvre Drupal
Appel de Web Service
● Utilisation du module wsclient
   ○ Permet de définir des "services"
   ○ Et sur chaque services, des "opérations"
● Différents types de services :
   ○ SOAP
   ○ REST
Appel de Web Service
● Les opérations sont définies avec
  ○ une URL
  ○ une Method HTTP
  ○ des paramètres
  ○ un type de retour
● Paramètres
  ○ Type, Required, Multiple, Default value
Appel de Web Service
● Paramétrage possible
    ○ depuis l'interface
    ○ via l'API
● L'utilisation de l'API offre plus de possibilités
    ○ Ex : HTTP Method de l'opération
    ○ Ex : Format à utiliser (Json, Form,...)
Appel de Web Service
 ● Une fois définis, les opérations peuvent être
    appelées via l'API

$serviceName = "notification";
$operationName = "send_message";

$service = wsclient_service_load($serviceName);

$service->invoke($operationName,
   array("message" => "Ceci est mon message"));
Déclenchement des envois de
message
● La solution :
   ○ Utiliser l'API de wsclient directement en
      l'implémentant dans un module
● Problème :
   ○ Tout doit être prévu dans le code (quand envoyer le
      message ? à qui ? ...)
Déclenchement des envois de
message
● Utilisation de Rules
  ○ wsclient expose les opérations sous forme d'actions
     Rules
  ○ Avec possibilité de renseigner les paramètres
● Avantages
  ○ Tout est configurable depuis le backoffice
  ○ Les valeurs des paramètres peuvent contenir des
     tokens
Intégration javascript "client"
● Pour communiquer avec NodeJS, il faut
   inclure un javascript côté client
   ○ Ce script doit être chargé systématiquement sur
      chaque page
● On doit aussi initialiser en js l'Id et les rôles
   de l' utilisateur
   ○ Utilisation de drupal_add_js()
Intégration javascript "client"
function node_demo_init() {
  drupal_add_js('http://localhost:8080/notifications.js',
    'file');

    global $user;
    drupal_add_js(array(
      'node_demo' => array(
        'uid' => $user->uid,
        'roles' => array_values($user->roles),
      )
    ), 'setting');
}
Résultat   [WARNING: PROTOTYPE]

      mguillermin/node-drupal-notifications-demo
Démonstration
Pistes d'amélioration
● Ajout de nouveaux attributs aux messages
  ○ Type
  ○ Priorité / "Sticky"
  ○ Emetteur
  ○ ...


● A ajouter à l'API REST, dans la définition de
  service wsclient et à gérer dans le javascript
  client
Pistes d'amélioration
● Gérer l'authentification utilisateur côté
  NodeJS
   ○ Pour s'assurer que l'ID utilisateur envoyé est bien
      celui de l'utilisateur courant


● Mécanisme de jeton envoyé par le client et
  vérifié par NodeJS auprès de Drupal (SSO)
   ○ Cette vérification renverrait l'ID et les rôles
      utilisateurs
Pistes d'amélioration
● Sécuriser l'API REST
   ○ Eviter qu'un tiers n'utilise l'API REST pour envoyer
      des messages en n'autorisant les envois de
      message que depuis Drupal


● Utilisation d'une clé d'API
   ○ la clé serait validée à chaque appel d'API
Pistes d'amélioration
● Améliorer l'UI des notifications
   ○ Afficher/cacher
   ○ Persister les notifications entre les pages (statut
      lu/non lu)


● Utiliser un vrai pub/sub pour la transmission
   ○ Redis, RabbitMQ, ØMQ…


● Les améliorations de performance du serveur
@naholyr / @mguillermin

Contenu connexe

Tendances

Cours php & Mysql - 3éme partie
Cours php & Mysql - 3éme partieCours php & Mysql - 3éme partie
Cours php & Mysql - 3éme partiekadzaki
 
Cours j query-id1575
Cours j query-id1575Cours j query-id1575
Cours j query-id1575kate2013
 
Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JSAbdoulaye Dieng
 
Cours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partieCours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partiekadzaki
 
Cours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partieCours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partiekadzaki
 
jQuery GTI780 & MTI780 ETS A09
jQuery   GTI780 & MTI780   ETS   A09jQuery   GTI780 & MTI780   ETS   A09
jQuery GTI780 & MTI780 ETS A09Claude Coulombe
 
Gwt fast overview_v1
Gwt fast overview_v1Gwt fast overview_v1
Gwt fast overview_v1David Herviou
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPKristen Le Liboux
 
AngularJS et autres techno frontend
AngularJS et autres techno frontendAngularJS et autres techno frontend
AngularJS et autres techno frontendyllieth
 

Tendances (20)

Cours php & Mysql - 3éme partie
Cours php & Mysql - 3éme partieCours php & Mysql - 3éme partie
Cours php & Mysql - 3éme partie
 
Cours design pattern m youssfi partie 3 decorateur
Cours design pattern m youssfi partie 3 decorateurCours design pattern m youssfi partie 3 decorateur
Cours design pattern m youssfi partie 3 decorateur
 
De Java à .NET
De Java à .NETDe Java à .NET
De Java à .NET
 
Cours j query-id1575
Cours j query-id1575Cours j query-id1575
Cours j query-id1575
 
Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)Support programmation orientée aspect mohamed youssfi (aop)
Support programmation orientée aspect mohamed youssfi (aop)
 
Traitement distribue en BIg Data - KAFKA Broker and Kafka Streams
Traitement distribue en BIg Data - KAFKA Broker and Kafka StreamsTraitement distribue en BIg Data - KAFKA Broker and Kafka Streams
Traitement distribue en BIg Data - KAFKA Broker and Kafka Streams
 
Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JS
 
Introduction au Jquery
Introduction au JqueryIntroduction au Jquery
Introduction au Jquery
 
Cours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partieCours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partie
 
Cours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partieCours php & Mysql - 5éme partie
Cours php & Mysql - 5éme partie
 
Introduction à Symfony
Introduction à SymfonyIntroduction à Symfony
Introduction à Symfony
 
Support Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFISupport Web Services SOAP et RESTful Mr YOUSSFI
Support Web Services SOAP et RESTful Mr YOUSSFI
 
jQuery GTI780 & MTI780 ETS A09
jQuery   GTI780 & MTI780   ETS   A09jQuery   GTI780 & MTI780   ETS   A09
jQuery GTI780 & MTI780 ETS A09
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
Gwt fast overview_v1
Gwt fast overview_v1Gwt fast overview_v1
Gwt fast overview_v1
 
Un exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHPUn exemple élémentaire d'application MVC en PHP
Un exemple élémentaire d'application MVC en PHP
 
Javascript
JavascriptJavascript
Javascript
 
AngularJS et autres techno frontend
AngularJS et autres techno frontendAngularJS et autres techno frontend
AngularJS et autres techno frontend
 
Support de cours angular
Support de cours angularSupport de cours angular
Support de cours angular
 
Support Java Avancé Troisième Partie
Support Java Avancé Troisième PartieSupport Java Avancé Troisième Partie
Support Java Avancé Troisième Partie
 

En vedette

What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.Apigee | Google Cloud
 
The Enterprise Case for Node.js
The Enterprise Case for Node.jsThe Enterprise Case for Node.js
The Enterprise Case for Node.jsNodejsFoundation
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationAndrew Rota
 
Ausgabe 1/2 2015
Ausgabe 1/2 2015Ausgabe 1/2 2015
Ausgabe 1/2 2015Roland Rupp
 
Gestion d'accueil
Gestion d'accueilGestion d'accueil
Gestion d'accueilVisu-ad
 
Unithé ou café: optimisation des grands systèmes électriques
Unithé ou café: optimisation des grands systèmes électriquesUnithé ou café: optimisation des grands systèmes électriques
Unithé ou café: optimisation des grands systèmes électriquesOlivier Teytaud
 
Soirée SOA - 2010-06-15 - Introduction par Logica
Soirée SOA - 2010-06-15 - Introduction par LogicaSoirée SOA - 2010-06-15 - Introduction par Logica
Soirée SOA - 2010-06-15 - Introduction par LogicaNormandy JUG
 
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...carole_raby
 
Présentation reso ef 69
Présentation reso ef 69Présentation reso ef 69
Présentation reso ef 69Philippe Cabon
 
Osm rouen aitf_juin2010_fv
Osm rouen aitf_juin2010_fvOsm rouen aitf_juin2010_fv
Osm rouen aitf_juin2010_fvPORHIEL Isabelle
 
Purpose of Missionary Work FRENCH
Purpose of Missionary Work FRENCHPurpose of Missionary Work FRENCH
Purpose of Missionary Work FRENCHdearl1
 
Tipps zur Landing Page Optimierung
Tipps zur Landing Page Optimierung Tipps zur Landing Page Optimierung
Tipps zur Landing Page Optimierung Q2E Contentdesign
 
La Santé Jessica & Jamie
La Santé  Jessica & JamieLa Santé  Jessica & Jamie
La Santé Jessica & Jamieguesta99f810
 
La pedagogie du projet
La pedagogie du projetLa pedagogie du projet
La pedagogie du projettjb47
 
Sustain 2.0 - Nachhaltigkeit und Web 2.0
Sustain 2.0 - Nachhaltigkeit und Web 2.0Sustain 2.0 - Nachhaltigkeit und Web 2.0
Sustain 2.0 - Nachhaltigkeit und Web 2.0Roland Dunzendorfer
 

En vedette (20)

What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.What's Better than Microservices? Serverless Microservices.
What's Better than Microservices? Serverless Microservices.
 
The Enterprise Case for Node.js
The Enterprise Case for Node.jsThe Enterprise Case for Node.js
The Enterprise Case for Node.js
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Operational Intelligence aus der cloud
Operational Intelligence aus der cloudOperational Intelligence aus der cloud
Operational Intelligence aus der cloud
 
Ausgabe 1/2 2015
Ausgabe 1/2 2015Ausgabe 1/2 2015
Ausgabe 1/2 2015
 
PHP: if-else
PHP: if-elsePHP: if-else
PHP: if-else
 
Gestion d'accueil
Gestion d'accueilGestion d'accueil
Gestion d'accueil
 
Unithé ou café: optimisation des grands systèmes électriques
Unithé ou café: optimisation des grands systèmes électriquesUnithé ou café: optimisation des grands systèmes électriques
Unithé ou café: optimisation des grands systèmes électriques
 
Soirée SOA - 2010-06-15 - Introduction par Logica
Soirée SOA - 2010-06-15 - Introduction par LogicaSoirée SOA - 2010-06-15 - Introduction par Logica
Soirée SOA - 2010-06-15 - Introduction par Logica
 
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...
LE TABLEAU NUMÉRIQUE INTERACTIF (TNI) PEUT-IL JOUER UN RÔLE DANS LA PERSÉVÉRA...
 
Présentation reso ef 69
Présentation reso ef 69Présentation reso ef 69
Présentation reso ef 69
 
Osm rouen aitf_juin2010_fv
Osm rouen aitf_juin2010_fvOsm rouen aitf_juin2010_fv
Osm rouen aitf_juin2010_fv
 
Purpose of Missionary Work FRENCH
Purpose of Missionary Work FRENCHPurpose of Missionary Work FRENCH
Purpose of Missionary Work FRENCH
 
B9 Handbuch
B9 HandbuchB9 Handbuch
B9 Handbuch
 
Tipps zur Landing Page Optimierung
Tipps zur Landing Page Optimierung Tipps zur Landing Page Optimierung
Tipps zur Landing Page Optimierung
 
Wilhelm Vogel -
Wilhelm Vogel - Wilhelm Vogel -
Wilhelm Vogel -
 
La Santé Jessica & Jamie
La Santé  Jessica & JamieLa Santé  Jessica & Jamie
La Santé Jessica & Jamie
 
La pedagogie du projet
La pedagogie du projetLa pedagogie du projet
La pedagogie du projet
 
Sustain 2.0 - Nachhaltigkeit und Web 2.0
Sustain 2.0 - Nachhaltigkeit und Web 2.0Sustain 2.0 - Nachhaltigkeit und Web 2.0
Sustain 2.0 - Nachhaltigkeit und Web 2.0
 
Swiss Cloud Conference 2014: Einleitung
Swiss Cloud Conference 2014: EinleitungSwiss Cloud Conference 2014: Einleitung
Swiss Cloud Conference 2014: Einleitung
 

Similaire à Mettez du temps réel dans votre Drupal avec Node JS

SPA avec Angular et SignalR (FR)
SPA avec Angular et SignalR (FR)SPA avec Angular et SignalR (FR)
SPA avec Angular et SignalR (FR)Rui Carvalho
 
OWF12/HTML 5 local storage , olivier thomas, cto at webtyss
OWF12/HTML 5 local storage , olivier thomas, cto at webtyssOWF12/HTML 5 local storage , olivier thomas, cto at webtyss
OWF12/HTML 5 local storage , olivier thomas, cto at webtyssParis Open Source Summit
 
NodeJS for Mobile App
NodeJS for Mobile AppNodeJS for Mobile App
NodeJS for Mobile AppHabib MAALEM
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mareValtech
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloudJoffrey Fu Hrer
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloudJoffrey Fu Hrer
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScriptKristen Le Liboux
 
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8DocDoku
 
Enib cours c.a.i. web - séance #6 : introduction à node js
Enib   cours c.a.i. web - séance #6 : introduction à node jsEnib   cours c.a.i. web - séance #6 : introduction à node js
Enib cours c.a.i. web - séance #6 : introduction à node jsHoracio Gonzalez
 
2014 04-09-fr - app dev series - session 4 - indexing
2014 04-09-fr - app dev series - session 4 - indexing2014 04-09-fr - app dev series - session 4 - indexing
2014 04-09-fr - app dev series - session 4 - indexingMongoDB
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016Antoine Rey
 
Tableau de bord Yammer sous SharePoint 2013
Tableau de bord Yammer sous SharePoint 2013Tableau de bord Yammer sous SharePoint 2013
Tableau de bord Yammer sous SharePoint 2013Philippe Sfeir
 
Devoxx: Tribulation d'un développeur sur le Cloud
Devoxx: Tribulation d'un développeur sur le CloudDevoxx: Tribulation d'un développeur sur le Cloud
Devoxx: Tribulation d'un développeur sur le CloudTugdual Grall
 
Activity
ActivityActivity
Activitydido
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptxEsokia
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Tugdual Grall
 
Web-In 2010: Programmation Native iOS (French)
Web-In 2010: Programmation Native iOS (French)Web-In 2010: Programmation Native iOS (French)
Web-In 2010: Programmation Native iOS (French)Fred Brunel
 

Similaire à Mettez du temps réel dans votre Drupal avec Node JS (20)

Introduction à node.js
Introduction à node.js Introduction à node.js
Introduction à node.js
 
SPA avec Angular et SignalR (FR)
SPA avec Angular et SignalR (FR)SPA avec Angular et SignalR (FR)
SPA avec Angular et SignalR (FR)
 
OWF12/HTML 5 local storage , olivier thomas, cto at webtyss
OWF12/HTML 5 local storage , olivier thomas, cto at webtyssOWF12/HTML 5 local storage , olivier thomas, cto at webtyss
OWF12/HTML 5 local storage , olivier thomas, cto at webtyss
 
NodeJS for Mobile App
NodeJS for Mobile AppNodeJS for Mobile App
NodeJS for Mobile App
 
Node.js, le pavé dans la mare
Node.js, le pavé dans la mareNode.js, le pavé dans la mare
Node.js, le pavé dans la mare
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloud
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloud
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8
Les Z'ApéroTech Toulouse #2 - Présentation des nouveautés de JakartaEE 8
 
Enib cours c.a.i. web - séance #6 : introduction à node js
Enib   cours c.a.i. web - séance #6 : introduction à node jsEnib   cours c.a.i. web - séance #6 : introduction à node js
Enib cours c.a.i. web - séance #6 : introduction à node js
 
2014 04-09-fr - app dev series - session 4 - indexing
2014 04-09-fr - app dev series - session 4 - indexing2014 04-09-fr - app dev series - session 4 - indexing
2014 04-09-fr - app dev series - session 4 - indexing
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016
 
Vert.x 3
Vert.x 3Vert.x 3
Vert.x 3
 
Tableau de bord Yammer sous SharePoint 2013
Tableau de bord Yammer sous SharePoint 2013Tableau de bord Yammer sous SharePoint 2013
Tableau de bord Yammer sous SharePoint 2013
 
Devoxx: Tribulation d'un développeur sur le Cloud
Devoxx: Tribulation d'un développeur sur le CloudDevoxx: Tribulation d'un développeur sur le Cloud
Devoxx: Tribulation d'un développeur sur le Cloud
 
Activity
ActivityActivity
Activity
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptx
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)
 
Vert.x
Vert.xVert.x
Vert.x
 
Web-In 2010: Programmation Native iOS (French)
Web-In 2010: Programmation Native iOS (French)Web-In 2010: Programmation Native iOS (French)
Web-In 2010: Programmation Native iOS (French)
 

Mettez du temps réel dans votre Drupal avec Node JS

  • 1. Mettez du temps réel dans votre Drupal avec NodeJS
  • 2. Qui sommes nous ? ● Matthieu Guillermin - Multitask Consultant chez @mguillermin ● Nicolas Chambrier - Nodefag Troll Développeur chez @naholyr
  • 3. Pourquoi intégrer Drupal / NodeJS ? ● On va de plus en plus vers des architectures hétérogènes ● Utiliser chaque techno pour ce qu'elle sait bien faire ● Les besoins de "temps-réels" sont de plus en plus présents
  • 5. Le Cas d'Utilisation ● Notre but était de : ○ Utiliser Drupal pour ce qu'il fait de mieux ○ Utiliser NodeJS pour ce qu'il fait de mieux ○ Trouver un cas d'utilisation réellement utile ● En utilisant des fonctionnalités classiques à la fois pour Drupal et pour NodeJS
  • 6. Le Cas d'Utilisation ● Drupal : ○ Gestion de contenu ○ Contribution ○ Workflow ● NodeJS : ○ Mise en place d'une API REST ○ Application "temps réel"
  • 7. Le Cas d'Utilisation ● Système de notification ○ Messages affichés directement dans le navigateur ○ En réponse à des événements Drupal ○ Envoi en "temps-réel" ● Paramétrable ○ Définition de règles d'envoi de messages ○ Définition des destinataires des message
  • 9. Comment le réaliser ? ● Utilisation de standards Web ● Communication depuis Drupal ○ Web Services ○ REST ● Communication depuis le client ○ Accès direct au serveur NodeJS
  • 10. Comment le réaliser ? Appel Web Service Serveur Drupal NodeJS Dispatch & Action Notification Navigateur Navigateur Navigateur client client client
  • 11. Mise en oeuvre NodeJS
  • 12. Comment on a travaillé ● Pas de super-héros ! ○ Je n'y connais rien à Drupal ○ Il n'y connait pas grand chose à Node ● Il faut: ○ Savoir installer et faire tourner le travail de l'autre ■ Drupal: LAMP + dump MySQL ■ Node: NodeJS → `node app.js` ○ Définir l'API avant tout ■ Sur un coin de table 3 jours avant ○ C'est tout !
  • 13. Un serveur HTTP + WebSocket ● On veut que ce soit simple ○ Toute la stack dans une seule application ○ Notifier = une requête HTTP simple ○ Afficher les notifications = une inclusion de script + une ligne de config ● On veut que ce soit sécurisé, performant, et scalable ○ Oui mais c'est un tout autre sujet ;)
  • 14. One app to rule them all var app = http.createServer(handler) Notifications function handler (req, res) { if (req.url === "/" && req.method === "POST") { newNotification(req, res) } else { Fichiers statiques serveStatic(req, res); } } WebSockets var io = require('socket.io') io.listen(app)
  • 15. Modèle de données ● Identifier les paramètres requis: ○ On veut un message → "message": String ○ On veut cibler les utilisateurs par rôle → "roles": [String] ○ On veut éventuellement cibler par utilisateur → "users": [String] ● JSON: { "roles": ["administrator"], "users": [1], "message": "hello, world" }
  • 16. API REST function newNotification (req, res) ● JSON { if (!isJSON(req)) { ● Création = POST error400() } ● Réponse adaptée: 201 - Created var notif = JSON.parse(req.body) 400 - Bad Request validateNotif(notif) 500 - Server Error notif.id = uuid() ● Broadcast via broadcastViaWebSocket(notif) WebSocket respond(res, 201, "application/json", JSON.stringify(notif)) }
  • 17. function display (id, roles) { API Client addJS("socket.io.js") addCSS("notifications.css") ● Script servi par addDOMContainer() l'application var socket = io.connect() ● Une seule fonction socket.on('connect', function () { socket.emit('roles', roles) ● Ajoute seul les socket.emit('user_id', id) dépendances }) JS & CSS socket.on('error', function (e) { notifyError(e) }) ● Enrichit le DOM socket.on('notif', function (n) { notifyInfo(n) }) ● Gère le WebSocket }
  • 18. API : Utilisation Client <script src="http://localhost:8080/notifications.js" ></script> <script>notifications.display(1, ["administrator"])</script> Serveur POST http://localhost:8080 Content-Type: application/json {"roles":["administrator"],"message":"Show me your big power"} Simple enough ?
  • 19. Socket.IO ● Pourquoi Socket.IO ? ○ Puissant, simple, efficace, hyper-compatible. ● Comment distribuer les messages ? ○ Filtrer côté client ? Pas efficace ○ Côté serveur: comment router les message ? ● Socket.IO à la rescousse: les "rooms": ○ Client: socket.join("room") ○ Serveur: io.sockets.in("room").emit(data) ○ Nos salons: "USER:$id" & "ROLE:$role" ● Problème des notifications en double
  • 20. Socket.IO - implémentation ● Client socket.on('connect', function () { socket.emit('user_id', user_id); }); socket.on('user_id', function (user_id) ● Serveur { socket.join('USER:' + user_id); }); notification.users.forEach(function (id) { ● Notification io.sockets .in('USER:' + id) .emit('notification', notification); });
  • 21. Résultat [WARNING: PROTOTYPE] naholyr/node-drupal-notifications
  • 22. Mise en oeuvre Drupal
  • 23. Appel de Web Service ● Utilisation du module wsclient ○ Permet de définir des "services" ○ Et sur chaque services, des "opérations" ● Différents types de services : ○ SOAP ○ REST
  • 24. Appel de Web Service ● Les opérations sont définies avec ○ une URL ○ une Method HTTP ○ des paramètres ○ un type de retour ● Paramètres ○ Type, Required, Multiple, Default value
  • 25. Appel de Web Service ● Paramétrage possible ○ depuis l'interface ○ via l'API ● L'utilisation de l'API offre plus de possibilités ○ Ex : HTTP Method de l'opération ○ Ex : Format à utiliser (Json, Form,...)
  • 26. Appel de Web Service ● Une fois définis, les opérations peuvent être appelées via l'API $serviceName = "notification"; $operationName = "send_message"; $service = wsclient_service_load($serviceName); $service->invoke($operationName, array("message" => "Ceci est mon message"));
  • 27. Déclenchement des envois de message ● La solution : ○ Utiliser l'API de wsclient directement en l'implémentant dans un module ● Problème : ○ Tout doit être prévu dans le code (quand envoyer le message ? à qui ? ...)
  • 28. Déclenchement des envois de message ● Utilisation de Rules ○ wsclient expose les opérations sous forme d'actions Rules ○ Avec possibilité de renseigner les paramètres ● Avantages ○ Tout est configurable depuis le backoffice ○ Les valeurs des paramètres peuvent contenir des tokens
  • 29. Intégration javascript "client" ● Pour communiquer avec NodeJS, il faut inclure un javascript côté client ○ Ce script doit être chargé systématiquement sur chaque page ● On doit aussi initialiser en js l'Id et les rôles de l' utilisateur ○ Utilisation de drupal_add_js()
  • 30. Intégration javascript "client" function node_demo_init() { drupal_add_js('http://localhost:8080/notifications.js', 'file'); global $user; drupal_add_js(array( 'node_demo' => array( 'uid' => $user->uid, 'roles' => array_values($user->roles), ) ), 'setting'); }
  • 31. Résultat [WARNING: PROTOTYPE] mguillermin/node-drupal-notifications-demo
  • 33. Pistes d'amélioration ● Ajout de nouveaux attributs aux messages ○ Type ○ Priorité / "Sticky" ○ Emetteur ○ ... ● A ajouter à l'API REST, dans la définition de service wsclient et à gérer dans le javascript client
  • 34. Pistes d'amélioration ● Gérer l'authentification utilisateur côté NodeJS ○ Pour s'assurer que l'ID utilisateur envoyé est bien celui de l'utilisateur courant ● Mécanisme de jeton envoyé par le client et vérifié par NodeJS auprès de Drupal (SSO) ○ Cette vérification renverrait l'ID et les rôles utilisateurs
  • 35. Pistes d'amélioration ● Sécuriser l'API REST ○ Eviter qu'un tiers n'utilise l'API REST pour envoyer des messages en n'autorisant les envois de message que depuis Drupal ● Utilisation d'une clé d'API ○ la clé serait validée à chaque appel d'API
  • 36. Pistes d'amélioration ● Améliorer l'UI des notifications ○ Afficher/cacher ○ Persister les notifications entre les pages (statut lu/non lu) ● Utiliser un vrai pub/sub pour la transmission ○ Redis, RabbitMQ, ØMQ… ● Les améliorations de performance du serveur