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

3 990 vues

Publié le

Publié dans : Technologie
0 commentaire
1 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Nombre de vues
3 990
Sur SlideShare
0
Issues des intégrations
0
Intégrations
493
Actions
Partages
0
Téléchargements
33
Commentaires
0
J’aime
1
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

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

×