37
Mettez du temps réel dans votre Drupal avec NodeJS

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

Embed Size (px)

DESCRIPTION

 

Citation preview

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

Mettez du temps réel dans votre Drupal avec NodeJS

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

Qui sommes nous ?

● Matthieu Guillermin - MultitaskConsultant chez @mguillermin

● Nicolas Chambrier - Nodefag TrollDéveloppeur chez @naholyr

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

● 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

Pourquoi intégrer Drupal / NodeJS ?

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

Le Cas d'Utilisation

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

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

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

Le Cas d'Utilisation

● Drupal :○ Gestion de contenu

○ Contribution

○ Workflow

● NodeJS :○ Mise en place d'une API REST

○ Application "temps réel"

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

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

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

Comment le réaliser ?

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

Comment le réaliser ?

● Utilisation de standards Web

● Communication depuis Drupal○ Web Services

○ REST

● Communication depuis le client○ Accès direct au serveur NodeJS

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

Comment le réaliser ?

Serveur NodeJSDrupal

Navigateur client

Navigateur clientNavigateur

client

Action

Appel Web Service

Dispatch & Notification

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

Mise en oeuvre NodeJS

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

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 !

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

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 ;)

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

One app to rule them all

Notifications

Fichiers statiques WebSockets

var app = http.createServer(handler) function handler (req, res) {

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

else { serveStatic(req, res); }}

var io = require('socket.io') io.listen(app)

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

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" }

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

API REST

● JSON

● Création = POST● Réponse adaptée:

201 - Created400 - Bad Request500 - Server Error

● Broadcast viaWebSocket

function newNotification (req, res) { if (!isJSON(req)) { error400() } var notif = JSON.parse(req.body) validateNotif(notif) notif.id = uuid() broadcastViaWebSocket(notif) respond(res, 201, "application/json", JSON.stringify(notif))}

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

API Client

● Script servi parl'application

● Une seule fonction

● Ajoute seul lesdépendancesJS & CSS

● Enrichit le DOM

● Gère le WebSocket

function display (id, roles) { addJS("socket.io.js") addCSS("notifications.css") addDOMContainer() var socket = io.connect() socket.on('connect', function () { socket.emit('roles', roles) socket.emit('user_id', id) }) socket.on('error', function (e) { notifyError(e) }) socket.on('notif', function (n) { notifyInfo(n) }) }

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

API : Utilisation

Client

Serveur

Simple enough ?

<script src="http://localhost:8080/notifications.js"></script><script>notifications.display(1, ["administrator"])</script>

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

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

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

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

Socket.IO - implémentation

● Client

● Serveur

● Notification

socket.on('connect', function () { socket.emit('user_id', user_id);});

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

notification.users.forEach(function (id) { io.sockets .in('USER:' + id) .emit('notification', notification);});

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

Résultat [WARNING: PROTOTYPE]

naholyr/node-drupal-notifications

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

Mise en oeuvre Drupal

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

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

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

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

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

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,...)

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

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"));

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

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 ? ...)

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

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

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

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()

Page 30: Mettez du temps réel dans votre Drupal avec Node 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');}

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

Résultat [WARNING: PROTOTYPE]

mguillermin/node-drupal-notifications-demo

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

Démonstration

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

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

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

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

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

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

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

● 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

Pistes d'amélioration

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

@naholyr / @mguillermin