Successfully reported this slideshow.
Mettez du temps réel dansvotre Drupal avec NodeJS
Qui sommes nous ?  ● Matthieu Guillermin - Multitask    Consultant chez      @mguillermin  ● Nicolas Chambrier - Nodefag T...
Pourquoi intégrer Drupal / NodeJS ?● On va de plus en plus vers des architectures  hétérogènes● Utiliser chaque techno pou...
Le Cas dUtilisation
Le Cas dUtilisation● Notre but était de :   ○ Utiliser Drupal pour ce quil fait de mieux   ○ Utiliser NodeJS pour ce quil ...
Le Cas dUtilisation● Drupal :  ○ Gestion de contenu  ○ Contribution  ○ Workflow● NodeJS :  ○ Mise en place dune API REST  ...
Le Cas dUtilisation● Système de notification  ○ Messages affichés directement dans le navigateur  ○ En réponse à des événe...
Comment le réaliser ?
Comment le réaliser ?● Utilisation de standards Web● Communication depuis Drupal  ○ Web Services  ○ REST● Communication de...
Comment le réaliser ?                Appel Web Service   Serveur   Drupal                                    NodeJS       ...
Mise en oeuvre NodeJS
Comment on a travaillé● Pas de super-héros !   ○ Je ny connais rien à Drupal   ○ Il ny connait pas grand chose à Node● Il ...
Un serveur HTTP + WebSocket● On veut que ce soit simple  ○ Toute la stack dans une seule application  ○ Notifier = une req...
One app to rule them all                     var app = http.createServer(handler)Notifications                     functio...
Modèle de données● Identifier les paramètres requis:   ○ On veut un message     → "message": String   ○ On veut cibler les...
API REST                       function newNotification (req, res)● JSON                 {                           if (!...
function display (id, roles) {API Client                 addJS("socket.io.js")                           addCSS("notificat...
API : UtilisationClient<script src="http://localhost:8080/notifications.js"></script><script>notifications.display(1, ["ad...
Socket.IO● Pourquoi Socket.IO ?  ○ Puissant, simple, efficace, hyper-compatible.● Comment distribuer les messages ?  ○ Fil...
Socket.IO - implémentation● Client         socket.on(connect, function () {                   socket.emit(user_id, user_id...
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 ...
Appel de Web Service● Les opérations sont définies avec  ○ une URL  ○ une Method HTTP  ○ des paramètres  ○ un type de reto...
Appel de Web Service● Paramétrage possible    ○ depuis linterface    ○ via lAPI● Lutilisation de lAPI offre plus de possib...
Appel de Web Service ● Une fois définis, les opérations peuvent être    appelées via lAPI$serviceName = "notification";$op...
Déclenchement des envois demessage● La solution :   ○ Utiliser lAPI de wsclient directement en      limplémentant dans un ...
Déclenchement des envois demessage● Utilisation de Rules  ○ wsclient expose les opérations sous forme dactions     Rules  ...
Intégration javascript "client"● Pour communiquer avec NodeJS, il faut   inclure un javascript côté client   ○ Ce script d...
Intégration javascript "client"function node_demo_init() {  drupal_add_js(http://localhost:8080/notifications.js,    file)...
Résultat   [WARNING: PROTOTYPE]      mguillermin/node-drupal-notifications-demo
Démonstration
Pistes damélioration● Ajout de nouveaux attributs aux messages  ○ Type  ○ Priorité / "Sticky"  ○ Emetteur  ○ ...● A ajoute...
Pistes damélioration● Gérer lauthentification utilisateur côté  NodeJS   ○ Pour sassurer que lID utilisateur envoyé est bi...
Pistes damélioration● Sécuriser lAPI REST   ○ Eviter quun tiers nutilise lAPI REST pour envoyer      des messages en nauto...
Pistes damélioration● Améliorer lUI des notifications   ○ Afficher/cacher   ○ Persister les notifications entre les pages ...
@naholyr / @mguillermin
Prochain SlideShare
Chargement dans…5
×

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

4 245 vues

Publié le

Publié dans : Technologie
  • Soyez le premier à commenter

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

  1. 1. Mettez du temps réel dansvotre Drupal avec NodeJS
  2. 2. Qui sommes nous ? ● Matthieu Guillermin - Multitask Consultant chez @mguillermin ● Nicolas Chambrier - Nodefag Troll Développeur chez @naholyr
  3. 3. Pourquoi intégrer Drupal / NodeJS ?● On va de plus en plus vers des architectures hétérogènes● Utiliser chaque techno pour ce quelle sait bien faire● Les besoins de "temps-réels" sont de plus en plus présents
  4. 4. Le Cas dUtilisation
  5. 5. Le Cas dUtilisation● Notre but était de : ○ Utiliser Drupal pour ce quil fait de mieux ○ Utiliser NodeJS pour ce quil fait de mieux ○ Trouver un cas dutilisation réellement utile● En utilisant des fonctionnalités classiques à la fois pour Drupal et pour NodeJS
  6. 6. Le Cas dUtilisation● Drupal : ○ Gestion de contenu ○ Contribution ○ Workflow● NodeJS : ○ Mise en place dune API REST ○ Application "temps réel"
  7. 7. Le Cas dUtilisation● 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 denvoi de messages ○ Définition des destinataires des message
  8. 8. Comment le réaliser ?
  9. 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. 10. Comment le réaliser ? Appel Web Service Serveur Drupal NodeJS Dispatch & Action Notification Navigateur Navigateur Navigateur client client client
  11. 11. Mise en oeuvre NodeJS
  12. 12. Comment on a travaillé● Pas de super-héros ! ○ Je ny connais rien à Drupal ○ Il ny connait pas grand chose à Node● Il faut: ○ Savoir installer et faire tourner le travail de lautre ■ Drupal: LAMP + dump MySQL ■ Node: NodeJS → `node app.js` ○ Définir lAPI avant tout ■ Sur un coin de table 3 jours avant ○ Cest tout !
  13. 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 cest un tout autre sujet ;)
  14. 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. 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. 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. 17. function display (id, roles) {API Client addJS("socket.io.js") addCSS("notifications.css")● Script servi par addDOMContainer() lapplication 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. 18. API : UtilisationClient<script src="http://localhost:8080/notifications.js"></script><script>notifications.display(1, ["administrator"])</script>ServeurPOST http://localhost:8080Content-Type: application/json{"roles":["administrator"],"message":"Show me your bigpower"}Simple enough ?
  19. 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. 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. 21. Résultat [WARNING: PROTOTYPE] naholyr/node-drupal-notifications
  22. 22. Mise en oeuvre Drupal
  23. 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. 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. 25. Appel de Web Service● Paramétrage possible ○ depuis linterface ○ via lAPI● Lutilisation de lAPI offre plus de possibilités ○ Ex : HTTP Method de lopération ○ Ex : Format à utiliser (Json, Form,...)
  26. 26. Appel de Web Service ● Une fois définis, les opérations peuvent être appelées via lAPI$serviceName = "notification";$operationName = "send_message";$service = wsclient_service_load($serviceName);$service->invoke($operationName, array("message" => "Ceci est mon message"));
  27. 27. Déclenchement des envois demessage● La solution : ○ Utiliser lAPI de wsclient directement en limplémentant dans un module● Problème : ○ Tout doit être prévu dans le code (quand envoyer le message ? à qui ? ...)
  28. 28. Déclenchement des envois demessage● Utilisation de Rules ○ wsclient expose les opérations sous forme dactions 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. 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 lId et les rôles de l utilisateur ○ Utilisation de drupal_add_js()
  30. 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. 31. Résultat [WARNING: PROTOTYPE] mguillermin/node-drupal-notifications-demo
  32. 32. Démonstration
  33. 33. Pistes damélioration● Ajout de nouveaux attributs aux messages ○ Type ○ Priorité / "Sticky" ○ Emetteur ○ ...● A ajouter à lAPI REST, dans la définition de service wsclient et à gérer dans le javascript client
  34. 34. Pistes damélioration● Gérer lauthentification utilisateur côté NodeJS ○ Pour sassurer que lID utilisateur envoyé est bien celui de lutilisateur courant● Mécanisme de jeton envoyé par le client et vérifié par NodeJS auprès de Drupal (SSO) ○ Cette vérification renverrait lID et les rôles utilisateurs
  35. 35. Pistes damélioration● Sécuriser lAPI REST ○ Eviter quun tiers nutilise lAPI REST pour envoyer des messages en nautorisant les envois de message que depuis Drupal● Utilisation dune clé dAPI ○ la clé serait validée à chaque appel dAPI
  36. 36. Pistes damélioration● Améliorer lUI 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
  37. 37. @naholyr / @mguillermin

×