Talk di Luca Lusso | Drupal Day Roma 2011
Snellire il carico del server per generare e restituire un json da usare per un autocompletamento. Notificare che un nodo è stato appena creato a tutti gli utenti che stanno visitando il sito in questo momento. Oppure ancora mettere a disposizione degli utenti una chat in tempo reale. Tutto questo (e molto altro) si può delegare ad un processo esterno a Drupal per aumentare velocità di interazione e diminuire il carico del server.
Durante il talk si vedrà come installare e usare node.js e come integrarlo con Drupal. Verrà mostrato il modulo nodejs presente nel repository di drupal.org
2. Cos’è e come funziona node.js
• Javascript sul server
• Basato su V8 di Google (il motore javascript di Chrome, open-source)
• Event driven
• I/O asincrono (mediante librerie esterne)
martedì 6 dicembre 11
3. Cos’è e come funziona node.js
• Un singolo processo gestisce il main event loop e tutte le connessioni (singolo thread)
• I task sono eseguiti in modo asincrono lasciando il main event loop libero di gestire altre richieste
• Anche nginx usa lo stesso modello semplicemente perché per una concorrenza massiva non
possiamo usare un thread del sistema operativo per ogni connessione, è troppo pesante
martedì 6 dicembre 11
4. Cos’è e come funziona node.js
processo di I/O (lento)
es.: attesa dati da un processo di I/O (veloce)
node webservice es.: query a Mongodb
A
Tempo
B
C
martedì 6 dicembre 11
5. Node.js può essere usato (e da il suo meglio) per
• Gestire la concorrenza
• I/O asincrono
• Networking
• Caricamento asincrono di componenti di una pagina via Ajax
martedì 6 dicembre 11
6. Node.js è sconsigliato per
• Generare intere pagine web
• Restituire grosse quantità di dati (download di file) -> ha un thread solo
martedì 6 dicembre 11
7. Dove si usa?
• Applicazione mobile di Linkedin
• Cloud9 (IDE su web)
• Nodejitsu (Cloud per applicazioni in node.js)
martedì 6 dicembre 11
8. Installare node.js
• http://nodejs.org/
• Ultima versione stabile (0.6.3) disponibile per tutti i sistemi operativi
• github.com/joyent/node/wiki/Installation
• Per Mac Os X e Windows è disponibile l’installer, per Linux basta scaricare il sorgente e compilare :-)
martedì 6 dicembre 11
9. Installare node.js
• NPM (Node Package Manager)
• Gestisce il download e l’installazione delle librerie aggiuntive
• http://npmjs.org/
• Su Linux, Mac Os X: curl http://npmjs.org/install.sh | sudo sh (su Windows è un po’ più
complesso)
• Attualmente sono disponibili più di 5000 librerie per i più svariati casi d’uso
• #> npm install express
martedì 6 dicembre 11
10. Hello world (hello.js)
var http = require('http');
http.createServer(function (request, response) {
console.log('Request received’);
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello Worldn');
}).listen(8000);
console.log('Server running at http://127.0.0.1:8000/');
martedì 6 dicembre 11
11. Hello world (hello.js)
funkymac2:Desktop lussoluca$ node hello.js
Server running at http://127.0.0.1:8000/
Request received
martedì 6 dicembre 11
12. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
• Chiama Ajax per autocompletare i tags durante la digitazione
• Necessita un bootstrap completo di Drupal per gestire la richiesta
• /taxonomy/autocomplete/field_tags/a
martedì 6 dicembre 11
13. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
• express (http://expressjs.com)
• web framework per Node.js
• Nel nostro esempio usiamo solo il routing, ma fa anche middleware, template e altro
• mysql (github.com/felixge/node-mysql)
• driver MySQL per node.js
martedì 6 dicembre 11
14. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
var Client = require('mysql').Client;
var client = new Client();
client.user = 'root';
client.password = 'root';
client.port = 3306;
client.database = 'drupaldb';
martedì 6 dicembre 11
15. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
var app = require('express').createServer();
app.get('/autocomplete/:vid/:id', function(req, res) {
martedì 6 dicembre 11
16. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
var query = client.query('SELECT * FROM [...]', [vid, arg, tags.join(',')],
function selectCb(err, results, fields) {
if (err) {
throw err;
Callback! Node.js non si ferma ad aspettare
}
i risultati dal db, li invierà al client quando
var names = {}; saranno pronti!
var prefix = (tags.length > 0) ? tags.join(',') + ', ' : '';
for (var i in results) {
var result = results[i];
names[prefix + result.name] = result.name;
}
res.write(JSON.stringify(names));
res.end(); // end the request.
});
martedì 6 dicembre 11
17. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
app.listen(3000);
martedì 6 dicembre 11
20. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
• /autocomplete/1/% non è un path Drupal
• Necessario per bypassare il problema del cross domain scripting
• Bisogna configurare il mod_proxy di Apache (cosa simile per nginx)
martedì 6 dicembre 11
21. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
Nella configurazione del VirtualHost
<VirtualHost *:80>
[...] diciamo ad Apache di girare le richieste
ProxyRequests Off
alla url “autocomplete” al server node.js in
ascolto sulla porta 3000
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /autocomplete http://www.example.it:3000/autocomplete
ProxyPassReverse /autocomplete http://www.example.it:3000/autocomplete
</VirtualHost>
martedì 6 dicembre 11
22. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
Esempio di vocabolario con 3000 termini
Node.js: 15ms Chiamata standard Drupal: 131ms
martedì 6 dicembre 11
23. Code session: realizzazione di un modulo per
l’autocompletamento dei tags
• Possibili migliorie (però con implementazione più complessa)
• Mongodb per memorizzare i termini
• Socket.io per ovviare al problema del cross domain scripting
martedì 6 dicembre 11
24. drupal.org/project/nodejs
• Ancora in versione beta (ma sviluppato attivamente)
• Canali multipli per inviare messaggi asincroni a tutti i client connessi al sito a seconda dei ruoli/
permessi
• Basato su Socket.io, express e connect
• Composto da uno script node.js e da un insieme di moduli Drupal
• nodejs_notify -> notifiche growl like
• nodejs_subscribe -> notifica cambiamenti nei contenuti
• nodejs_actions -> action per inviare messaggi, usabile anche da Rules
martedì 6 dicembre 11
25. drupal.org/project/nodejs
client Drupal
Richiesta iniziale
Risposta con token di autenticazione
node
Invio token
Verifica autenticazione
Lista canali
Autenticazione riuscita
Le chiamate successive non
passano più da Drupal
martedì 6 dicembre 11
26. Domande ?!
(se non basta il tempo o volete vedere una demo ci
vediamo al desk Wellnet)
martedì 6 dicembre 11
27. Luca Lusso
www.wellnet.it
it.linkedin.com/pub/luca-lusso/29/3a9/1a2
martedì 6 dicembre 11