Node.js

Pour cette compétence, j’ai choisi de suivre quelques tutorials dont j’ai synthétisé des informations d’introduction ci-dessous. Ensuite, j’ai utilisé le livre prêté par M. Blanvillain, “Programmation avec Node.js, Express.js et MongoDB : JavaScript coté serveur” par Éric Sarrion. J’ai pu mieux comprendre ce qu’est Node.js, c’est à dire un environnement javascript que l’on pourrait comparer à la ligne de commande ou powershell. J’ai pu suivre les parties traitant de la console, les événements, les timers, le buffer, les url (path, querystring) et le http. J’ai mis en pratique un maximum d’exemples fournis dans le livre.

Je n’ai pas (encore) traité les parties concernant les streams, les fichiers et les connexions TCP et UDP car cela s’éloignait de l’objet du cours de WEBA et des objectifs de cette compétence.

Pour terminer, j’ai fait la partie du cours sur Openclassrooms sur le module stream.io et qui consistait à mettre en pratique ce module node.js afin de construire un mini-site pour chatter en temps réel.

Node.js c’est quoi ?

Node.js est un environnement d’exécution open source gratuit et disponible sur différentes plateformes (tels que Windows, Linux, OSX, …). Il permet de faire fonctionner du code JavaScript sur le serveur.

Ce n’est pas exclusivement un serveur web car il pourrait faire tourner une application de traitement de fichiers.

A la différence des autres serveurs web communs, Node.js permet de la programmation asynchrone.

D’un point de vue développeur Node.js est un environnement d’exécution “single-threaded” basé sur le même moteur JavaScript disponible dans Chrome. Pour pouvoir offrir une E/S asynchronique, Node.js s’appuie sur libuv (Unicorn Velociraptor Library), une bibliothèque d’abstraction I/O fournissant un accès asynchronique basé sur des “event loops”, soit une construction programmatique qui attend et dispatche des événements ou messages au sein d’un programme.

Source : blog.risingstack.com/node-hero-tutorial-getting-started-with-node-js/, en.wikipedia.org/wiki/Libuv et en.wikipedia.org/wiki/Event_loop

Installation et configuration de Node.js

Sur Ubuntu (mon serveur préféré) :

$ curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
$ sudo apt-get install && sudo apt-get upgrade
$ sudo apt-get install -y nodejs
$ node --version

 Note : la première ligne sert à télécharger et exécuter le script de configuration du repository Node.js sur un système Debian ou Ubuntu 

Source : github.com/nodesource/distributions/blob/master/README.md#debinstal

Quelques notions relatives

La programmation asynchrone

Exemple : avec php

  1. la tâche est envoyée au système
  2. php attend que la tâche soit terminée
  3. le résultat est retourné au client
  4. php est prêt pour la requête suivante

avec node.js

  1. la tâche est envoyée au système
  2. node.js est prêt pour la requête suivante
  3. le résultat est retourné lorsqu’il sera prêt

Avec la programmation procédurale, une tâche ne peut commencer qu’une fois la précédente achevée.

Lors de la programmation asynchrone, les opérations d’I/O ne se sont pas bloquantes pour le système. Celles-ci tournent “en arrière plan” et un “event loop” se charge de vérifier quand la tâche est terminée le relais est effectué par les callbacks.

Les callbacks

C’est une fonction (souvent anonyme) passée en paramètre d’une autre fonction et qui est exécutée une fois que l’opération principale réalisée elle est déclenchée par le “event-loop”, lorsque il reçoit un signal de fin de tâche ou un message (success, error).

Exemple avec jQuery : $.get(‘page.php’, function(){ alert(‘page.php a été appelé’); });

Cependant, c’est un concept programmatique, que l’on peut l’implémenter “manuellement” de cette manière :

function doSomething(message, toDoOnceCompleted){
  console.log(message);
  toDoOnceCompleted();
}
doSomething("Hello", function(){
  alert("A message has been written to console log.")
});

Note

C’est Node.js qui contient lui-même un module de serveur web (http), c’est à dire que l’on va expressément demander à javascript de créer un serveur http qui va recevoir des requêtes sur un certain port.

Exemple :

myfirsttest.js
var http = require('http');
//create a server object:
http.createServer(function (req, res) {
  res.write('Hello World!'); //write a response to the client
  res.end(); //end the response
}).listen(8080); //the server object listens on port 8080 

pour démarrer l’application : 

node myfirsttest.js

source : www.w3schools.com/nodejs/nodejs_get_started.asp

Node.js et les modules

Les modules sont des bouts de code comme les bibliothèques en JavaScript. Ils sont appelés par la commande require().

Référence des modules de Node.js : www.w3schools.com/nodejs/ref_modules.asp

Il est possible de concevoir ses propres modules en utilisant le mot-clé exports

Exemple (source : www.w3schools.com/nodejs/nodejs_modules.asp)

myfirstmodule.js
exports.myDateTime = function () {
  return Date();
};

qui sera appelé de cette manière :

myfirsttest.js
var dt = require('./myfirstmodule');
(...)
res.write("The date and time are currently: " + dt.myDateTime());
(...)

Modules (2)

Query String (url demandée)

Si la réponse au client est supposée être interprétée comme du code html, il faut le spécifier comme tel :

res.writeHead(200, {'Content-Type': 'text/html'}); 

Note : 200 = code de statut html : OK

Liste des codes de status HTTP en.wikipedia.org/wiki/List_of_HTTP_status_codes

On peut récupérer la page demandée en utilisant l’argument res passée à l’objet http.createServer()

res.write(req.url); 

On peut aussi parser une url composée d’arguments comme /?id=2019 à l’aide de la fonction parse contenue dans le module url

var url = require('url');
(...)
url.parse(req.url, true).query;

File system

Il est aussi possible de manipuler des fichiers avec le module fs (filesystem) qui permet de lire, créer, mettre à jour, supprimer et renommer des fichiers.

NPM (Node.js package manager)

C’est une application de gestionnaire de paquets qui permet d’enrichir Node.js avec des modules externes ainsi que leur dépendances.

Beaucoup sont gratuits (licence MIT), documentés et disponibles sur www.npmjs.com

Evénements

Node.js peut être utilisé pour des applications basées sur des événements (ouvrir un fichier par exemple)

Exemple :

var fs = require('fs');
var rs = fs.createReadStream('./demofile.txt');
rs.on('open', function () {
  console.log('The file is open');
}); 

source : www.w3schools.com/nodejs/nodejs_events.asp

Event module & EventEmitter object

Exemple (même source que ci-desus):

var events = require('events');
var eventEmitter = new events.EventEmitter();

//Create an event handler:
var myEventHandler = function () {
  console.log('I hear a scream!');
}
//Assign the event handle to an event:
eventEmitter.on('scream', myEventHandler);

//Fire the 'scream' event:
eventEmitter.emit('scream'); 

Upload de fichiers

Il y a un package très utile, Formidable, disponible sur NPM : npm install formidable 

Les fichiers uploadés sont stockés dans un répertoire temporaire il peut être déplacé avec le module fs.

Exemple :

var http = require('http');
var formidable = require('formidable');
var fs = require('fs');
http.createServer(function (req, res) {
  if (req.url == '/fileupload') {
    var form = new formidable.IncomingForm();
    form.parse(req, function (err, fields, files) {
      var oldpath = files.filetoupload.path;
      var newpath = 'C:/Users/Your Name/' + files.filetoupload.name;
      fs.rename(oldpath, newpath, function (err) {
        if (err) throw err;
        res.write('File uploaded and moved!');
        res.end();
      });
 });
  } else {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write('<form action="fileupload" method="post" enctype="multipart/form-data">');
    res.write('<input type="file" name="filetoupload"><br>');
    res.write('<input type="submit">');
    res.write('</form>');
    return res.end();
  }
}).listen(8080);

source : www.w3schools.com/nodejs/nodejs_uploadfiles.asp

Ressources :

Apache/PHP Multi-threading
https://www.quora.com/What-is-the-fundamental-difference-between-Apache+PHP-and-Nginx+PHP-setup-in-terms-of-multi-threading-and-performance

Des serveurs web et des threads
https://openclassrooms.com/fr/courses/1056721-des-applications-ultra-rapides-avec-node-js/1057142-une-premiere-application-avec-node-js

Repository Bitbucket
https://bitbucket.org/FrankTheodoloz/weba-nodejs/commits/tag/WEBA-NodeJS-Competence


Posted

in

by

Tags: