Vous êtes sur la page 1sur 117

Sauf mention contraire, le contenu de cet ouvrage est publi sous la licence :

Creative Commons BY-NC-SA 2.0


La copie de cet ouvrage est autorise sous rserve du respect des conditions de la licence
Texte complet de la licence disponible sur : http : //creativecommons.org/licenses/by-nc-sa/2.0/fr/
OpenClassrooms 2014 - ISBN : 979-10-90085-61-9
Mentions lgales :
Conception couverture : Amalgam Impression
Illustrations chapitres : Alexandra Persil

Avant-propos
avaScript est dcidment un langage tonnant. Lanc par Brendan Eich en 1995
dans le navigateur Netscape pour permettre le dveloppement ct client (cest-dire lexcution de code sur la machine du visiteur), il est aujourdhui devenu un
langage incontournable du Web.

Jusquici, JavaScript pouvait tre utilis uniquement du ct client... et voil que depuis
peu il est aussi possible de lutiliser pour dvelopper ct serveur ! PHP, Java, Python,
Ruby et les autres nont qu bien se tenir !
Tout le petit monde du dveloppement web est en bullition et na dyeux que pour
Node.js et les perspectives quil ouvre pour le dveloppement en JavaScript ct serveur.
Pourquoi ? Parce que la conception de Node.js est trs diffrente de ce quon a lhabitude
de voir. Tout est bas sur un systme dvnements qui lui permet dtre extrmement
efficace, ce qui lui confre sa rputation de rapidit... et aussi une certaine complexit
parfois, il faut bien lavouer !
Mon but dans ce cours est de vous faire dcouvrir lutilisation de Node.js pas pas
avec plusieurs applications pratiques. tant donn que Node.js est assez complexe
prendre en main, jai fait de mon mieux pour que votre apprentissage soit le plus
progressif possible et que vous preniez autant de plaisir que moi avec cette nouvelle
faon de programmer !

Quallez-vous apprendre en lisant ce livre ?


Ce livre a t conu en partant du principe que vous connaissez dj le langage JavaScript. En effet, Node.js est directement bas sur JavaScript et il ne mest pas possible
de vous enseigner les deux la fois 1 ! Cependant, je ferai des rappels rgulirement
pour les notions les plus dlicates.
Voici les diffrentes parties qui jalonnent ce cours :
1. Comprendre Node.js : cette premire partie sera loccasion de faire des rappels sur JavaScript, son histoire et la naissance de Node.js. Nous installerons
Node.js et nous crerons notre premire application pas pas ensemble ;
1. Dautant plus quun excellent livre "Dynamisez vos sites web avec JavaScript" existe dj dans
la mme collection !

CHAPITRE 0. AVANT-PROPOS
2. Structurer son application Node.js : ce sera le moment de rentrer plus en
profondeur dans le fonctionnement dune application Node.js. Nous parlerons
dvnements, de modules et du framework Express.js, puis raliserons ensemble
une todo list ;
3. La communication temps rel avec socket.io : socket.io est lune des bibliothques les plus clbres de Node.js car elle permet une communication en
temps rel dans les deux sens entre le client et le serveur. A la cl : nous serons
capables de raliser un vritable Chat temps rel en ligne !

Comment lire ce livre ?


Suivez lordre des chapitres
Lisez ce cours comme on lit un roman. Il a t conu pour cela.
Contrairement beaucoup de livres techniques o il est courant de lire en diagonale et
de sauter certains chapitres, il est ici trs fortement recommand de suivre lordre du
cours, moins que vous ne soyez dj un peu expriments.

Pratiquez en mme temps


Pratiquez rgulirement. Nattendez pas davoir fini de lire ce livre pour allumer votre
ordinateur et faire vos propres essais.

Utilisez les codes web !


Afin de tirer parti dOpenClassrooms dont ce livre est issu, celui-ci vous propose ce
quon appelle des codes web . Ce sont des codes six chiffres saisir sur une page
dOpenClassrooms pour tre automatiquement redirig vers un site web sans avoir
en recopier ladresse.
Pour utiliser les codes web, rendez-vous sur la page suivante :
http://www.openclassrooms.com/codeweb
Un formulaire vous invite rentrer votre code web. Faites un premier essai avec le code
ci-dessous :


Tester le code web
B
Code web : 123456


Ces codes web ont deux intrts :
ils vous redirigent vers les sites web prsents tout au long du cours, vous permettant ainsi dobtenir les logiciels dans leur toute dernire version ;
ils vous permettent dafficher les codes sources inclus dans ce livre, ce qui vous
vitera davoir recopier certains programmes un peu longs.
ii

COMMENT LIRE CE LIVRE ?


Ce systme de redirection nous permet de tenir jour le livre que vous avez entre les
mains sans que vous ayez besoin dacheter systmatiquement chaque nouvelle dition.
Si un site web change dadresse, nous modifierons la redirection mais le code web
utiliser restera le mme. Si un site web disparat, nous vous redirigerons vers une page
dOpenClassrooms expliquant ce qui sest pass et vous proposant une alternative.
En clair, cest un moyen de nous assurer de la prennit de cet ouvrage sans que vous
ayez faire quoi que ce soit !

iii

CHAPITRE 0. AVANT-PROPOS

iv

Table des matires

Avant-propos

Comment lire ce livre ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ii

Suivez lordre des chapitres . . . . . . . . . . . . . . . . . . . . . . . . .

ii

Pratiquez en mme temps . . . . . . . . . . . . . . . . . . . . . . . . . .

ii

Utilisez les codes web ! . . . . . . . . . . . . . . . . . . . . . . . . . . . .

ii

Comprendre Node.js

1 Node.js : mais quoi a sert ?

Du JavaScript la papa Node.js . . . . . . . . . . . . . . . . . . . . . .

Node.js : le JavaScript ct serveur . . . . . . . . . . . . . . . . . . . . . . . .

Pourquoi Node.js est-il rapide ? . . . . . . . . . . . . . . . . . . . . . . . . . .

Le moteur V8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Le modle non bloquant . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 Installer Node.js
Installation de Node.js sous Windows

13
. . . . . . . . . . . . . . . . . . . . . .

14

Installation de Node.js sous Mac OS X . . . . . . . . . . . . . . . . . . . . . .

17

Installation de Node.js sous Linux . . . . . . . . . . . . . . . . . . . . . . . .

19

Tester Node.js avec un programme minimal . . . . . . . . . . . . . . . . . . .

20

3 Une premire application avec Node.js


Des serveurs web et des threads . . . . . . . . . . . . . . . . . . . . . . . . . .
v

23
24

TABLE DES MATIRES

II

Construire son serveur HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . .

25

Dissquons du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

Tester le serveur HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

Retourner du code HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

Dterminer la page appele et les paramtres . . . . . . . . . . . . . . . . . .

31

Quelle est la page demande par le visiteur ? . . . . . . . . . . . . . . . .

31

Quels sont les paramtres ? . . . . . . . . . . . . . . . . . . . . . . . . .

33

Schma rsum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

Structurer son application Node.js

4 Les vnements

37

couter des vnements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

38

mettre des vnements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

40

5 Les modules Node.js et NPM

43

Crer des modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44

Utiliser NPM pour installer des modules . . . . . . . . . . . . . . . . . . . . .

46

Trouver un module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

47

Installer un module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

48

Linstallation locale et linstallation globale . . . . . . . . . . . . . . . .

49

Mettre jour les modules . . . . . . . . . . . . . . . . . . . . . . . . . .

50

Dclarer et publier son module . . . . . . . . . . . . . . . . . . . . . . . . . .

50

Le fonctionnement des numros de version . . . . . . . . . . . . . . . . .

51

La gestion des versions des dpendances . . . . . . . . . . . . . . . . . .

52

Publier un module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

52

6 Le framework Express.js

vi

35

55

Les routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

56

Routes simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

56

Routes dynamiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

58

Les templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

59

Les bases dEJS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

60

Plusieurs paramtres et des boucles . . . . . . . . . . . . . . . . . . . . .

60

Aller plus loin : Connect et les middlewares . . . . . . . . . . . . . . . . . . .

61

TABLE DES MATIRES


Express, connect et les middlewares

. . . . . . . . . . . . . . . . . . . .

62

Utiliser les fonctionnalits de Connect au sein dExpress . . . . . . . . .

64

7 TP : la todo list

67

Besoin daide ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

68

Les modules et le package.json . . . . . . . . . . . . . . . . . . . . . . .

68

Les routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

69

Bien chaner les appels aux middlewares . . . . . . . . . . . . . . . . . .

70

Correction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71

La solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

71

Les explications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

73

Tlcharger le projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

74

Allez plus loin ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

74

III

La communication temps rel avec socket.io

8 socket.io : passez au temps rel !

75
77

Que fait socket.io ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

78

mettre et recevoir des messages avec socket.io . . . . . . . . . . . . . . . . .

80

Installer socket.io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

80

Premier code : un client se connecte . . . . . . . . . . . . . . . . . . . .

80

Envoi et rception de messages . . . . . . . . . . . . . . . . . . . . . . .

83

Communiquer avec plusieurs clients

. . . . . . . . . . . . . . . . . . . . . . .

87

Envoyer un message tous les clients (broadcast) . . . . . . . . . . . . .

87

Les variables de session . . . . . . . . . . . . . . . . . . . . . . . . . . .

88

9 TP : le super Chat

95

Besoin daide ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

96

package.json . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

97

app.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

97

index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

98

Correction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

98

package.json . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

99

app.js . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

99

index.html . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
vii

TABLE DES MATIRES


Tlcharger le projet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Allez plus loin ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

viii

Premire partie

Comprendre Node.js

Chapitre

Node.js : mais quoi a sert ?


Difficult :
Et si on commenait par rpondre toutes ces questions qui vous taraudent :
Pourquoi Node.js semble-t-il aussi apprci des dveloppeurs web ?
Pourquoi avoir utilis un langage commeJavaScript ? Je croyais que ctait juste
pour faire des effets dans sa page web ?
Do vient cette rapidit suppose de Node.js ? quoi a peut me servir ?
Est-ce que ce truc est mature ? Qui lutilise ( part des geeks barbus !) ? Devrais-je
lutiliser moi aussi ?
Je vais rpondre toute vos interrogations, et mme aux questions que vous ne vous posez
pas, dans ce premier chapitre. Et si laventure vous tente, vous pourrez passer la suite
avec moi et installer Node.js sur votre machine !

CHAPITRE 1. NODE.JS : MAIS QUOI A SERT ?

Du JavaScript la papa Node.js


OK, lexpression JavaScript la papa est un peu forte, mais il y a du vrai l-dedans :
JavaScript a eu plusieurs vies. Il a eu mauvaise presse. On la longtemps considr
comme un petit truc parfois bien pratique pour faire des effets sur sa page web .
Or, JavaScript est avant tout un langage au mme titre que C, Ruby, PHP et bien
dautres.
Dsormais, JavaScript est de retour et il prend sa revanche. Les dveloppeurs sont en
train de dcouvrir que ce langage quils ont longtemps ignor, parfois mme mpris,
cache en fait bien son jeu.
Non, JavaScript nest pas juste un petit langage utilitaire. Oui, JavaScript est un
langage part, qui sutilise vraiment diffremment de Java, du C et dun tas dautres
langages. Oui, JavaScript peut tre compliqu utiliser, mais recle une vritable
puissance.
Alors que ce langage a t cr en 1995 (la prhistoire de linformatique, rendez-vous
compte !), il a depuis bien volu. Je vous invite (re)lire la petite histoire de Javascript,
raconte par les compres Sbastien de la Marck et Johann Pardanaud dans leur cours
intitul "Dynamisez vos sites web avec Javascript !" que vous retrouverez sur le site
dOpenclassrooms.
Je vous disais que JavaScript tait un langage qui avait connu plusieurs vies. Pour
tre plus prcis, je dirais mme quil a connu trois vies (comme lillustre la figure 1.1) :
1. Dans les annes 90, on parlait de DHTML (Dynamic HTML). On utilisait
en fait les toutes premires versions de JavaScript pour crer des petits effets
dans ses pages web : afficher une image lors dun clic sur un bouton par exemple.
Ctait lpoque de Netscape et dInternet Explorer 5.5.
2. Dans les annes 2000, on a commenc utiliser le langage pour crer des interfaces ct client. Cest l que des bibliothques comme jQuery ou Mootools
sont apparues. Aujourdhui, cet usage de JavaScript est trs rpandu et mature. On a pris lhabitude de manipuler le DOM (Document Object Model) pour
affecter ses balises HTML en JavaScript et leur faire subir toutes sortes de
traitements.
3. Puis, aux alentours de 2010, JavaScript est entr dans une nouvelle re. Google
a commenc rendre le langage beaucoup plus rapide avec lapparition du navigateur Google Chrome. Avec ce navigateur est n le moteur dexcution V8
qui a considrablement permis dacclrer lexcution de code JavaScript (jy
reviendrai). Des outils comme Node.js sont ensuite apparus. Les bibliothques
dont le nom finit par .js se sont multiplies : Backbone.js, Ember.js, Meteor.js. JavaScript a lair nouveau cool et semble en mme temps plus
compliqu quil ny parait au premier abord.
Soyons clairs : jQuery nest pas mort et a ne veut pas dire quil faut cesser de lutiliser
(par contre DHTML et Netscape sont bel et bien morts eux). Les nouveaux outils
JavaScript comme Node.js font des choses trs diffrentes de jQuery et consorts.
Les deux peuvent tout fait se complter.
4

NODE.JS : LE JAVASCRIPT CT SERVEUR

Figure 1.1 Les trois vies de JavaScript

Mais a apporte quoi concrtement Node.js ?

Node.js nous permet dutiliser le langage JavaScript sur le serveur. . . Il nous


permet donc de faire du JavaScript en dehors du navigateur ! Node.js bnficie de
la puissance de JavaScript pour proposer une toute nouvelle faon de dvelopper des
sites web dynamiques.
Je vous propose justement de rentrer maintenant dans le dtail du fonctionnement de
Node.js.

Node.js : le JavaScript ct serveur


Jusquici, JavaScript avait toujours t utilis du ct du client, cest--dire du ct
du visiteur qui navigue sur notre site. Le navigateur web du visiteur (Firefox, Chrome,
IE. . .) excute le code JavaScript et effectue des actions sur la page web. (Voir figure
1.2)

Quest-ce qui change avec larrive de Node.js ?

On peut toujours utiliser du JavaScript ct client pour manipuler la page HTML.


5

CHAPITRE 1. NODE.JS : MAIS QUOI A SERT ?

Figure 1.2 Le schma classique : PHP sur le serveur, JavaScript chez le client
a, a ne change pas.
Par contre, Node.js offre un environnement ct serveur qui nous permet aussi dutiliser le langage JavaScript pour gnrer des pages web. En gros, il vient en remplacement de langages serveur comme PHP, Java EE, etc. (Voir la figure 1.3)

Figure 1.3 Avec Node.js, on peut aussi utiliser du JavaScript sur le serveur !

Pourquoi Node.js semble-t-il si diffrent ? Parce quil utilise JavaScript ?

Oui, et parce que JavaScript est un langage bas sur les vnements, donc Node.js
est lui-mme bas sur les vnements. Du coup, cest toute la faon dcrire des
applications web qui change ! Cest de l que Node.js tire toute sa puissance et sa
rapidit.
6

POURQUOI NODE.JS EST-IL RAPIDE ?


Avec Node.js, vous pouvez crer des applications rapides comme :
Un serveur de Chat.
Un systme dupload trs rapide.
Et de faon gnrale, nimporte quelle application qui doit rpondre de nombreuses requtes rapidement et efficacement, en temps rel.
Node.js nest pas un framework. Node.js est un environnement trs bas
niveau. Il se rapproche donc en quelque sorte plus du C que de PHP, Ruby on
Rails ou Django. Voil pourquoi il nest pas vraiment conseill aux dbutants.
Notez cependant quil existe des frameworks web comme Express qui sont
bass sur Node.js. Ils nous permettent dviter les tches rptitives qui nous
sont imposes par la nature bas niveau de Node.js, mais ils restent quand
mme plus complexes utiliser que des langages comme PHP.
JavaScript nest pas vraiment un langage Orient Objet, il est donc trs loin de Java,
Ruby ou Python. crire une application avec Node.js demande une gymnastique
desprit compltement diffrente ! Cest un peu droutant au dbut pour tout vous
avouer, mais quand on commence matriser cet outil, on se sent un peu comme si on
venait davoir de nouveaux super-pouvoirs quon ne souponnait pas. Voil pourquoi
tant de geeks barbus sont excits propos de Node.js ! (Voir figure 1.4)

Figure 1.4 Avant, jtais un barbu. . .

Pourquoi Node.js est-il rapide ?


Si Node.js est rapide, cela tient principalement deux choses : le moteur V8 et son
fonctionnement non bloquant.
7

CHAPITRE 1. NODE.JS : MAIS QUOI A SERT ?

Le moteur V8
Node.js utilise le moteur dexcution ultrarapide V8 de Google Chrome. Ce
moteur V8 avait beaucoup fait parler de lui la sortie de Google Chrome, car cest
un outil open source cr par Google qui analyse et excute du code JavaScript trs
rapidement. (Voir figure 1.5)

Figure 1.5 Le logo du moteur JavaScript V8 de Google


Jusqu la sortie de Chrome, la plupart des navigateurs lisaient le code JavaScript
de faon peu efficace : le code tait lu et interprt au fur et mesure. Le navigateur
mettait beaucoup de temps lire le JavaScript et le transformer en code machine
comprhensible pour le processeur.
Le moteur V8 de Google Chrome, qui est rutilis ici par Node.js, fonctionne compltement diffremment. Trs optimis, il fait ce quon appelle de la compilation JIT
(Just In Time). Il transforme le code JavaScript trs rapidement en code machine
et loptimise mme grce des procds complexes : code inlining, copy elision et
jen passe.
Vous navez pas besoin de connatre le fonctionnement de V8 pour utiliser Node.js.
Retenez juste quil permet de rendre lexcution de code JavaScript ultrarapide (et
que les dveloppeurs chez Google qui lont conu sont de bons vrais barbus :- ).

Le modle non bloquant


Comme JavaScript est un langage conu autour de la notion dvnement, Node.js
a pu mettre en place une architecture de code entirement non bloquante. Mais au fait,
connaissez-vous la diffrence entre un code bloquant et un code non bloquant ?
Hmmm, un peu dexplication ne peut pas faire de mal !
Modle bloquant vs modle non bloquant
Imaginez un programme dont le rle est de tlcharger un fichier puis de lafficher.
Voici comment on crirait le code dans un modle bloquant :
1
2
3

T l charger un fichier
Afficher le fichier
Faire autre chose

Les actions sont effectues dans lordre. Il faut lire les lignes de haut en bas :
1. Le programme va tlcharger un fichier sur Internet.
2. Le programme affiche le fichier lutilisateur.
8

POURQUOI NODE.JS EST-IL RAPIDE ?


3. Ensuite, le programme peut faire dautres choses (effectuer dautres actions).
Maintenant, on peut crire le mme code sur un modle non bloquant :
1
2
3

T l charger un fichier
D s que c ' est termin , afficher le fichier
Faire autre chose

Le programme nexcute plus les lignes dans lordre o elles sont crites. Il fait ceci :
1. Le programme lance le tlchargement dun fichier sur Internet.
2. Le programme fait dautres choses (le programme suit son cours).
3. Ds que le tlchargement est termin, le programme effectue les actions quon
lui avait demandes : il affiche le fichier.
Schmatiquement, lexcution du programme peut donc se reprsenter comme la figure
1.6.

Figure 1.6 Le modle non bloquant en programmation


Cest justement comme a que fonctionne Node.js. Ds que lvnement Fichier tlcharg apparat, une fonction appele fonction de callback est appele et effectue
des actions (ici, la fonction de callback affiche le fichier).
Le modle non bloquant avec Node.js
Et avec du vrai code a donne quoi ? Voici un exemple de programme Node.js qui
tlcharge un fichier sur Internet et affiche Fichier tlcharg ! quand il a termin :
1
2

request ( ' http :// www . site . com / fichier . zip ' , function ( error ,
response , body ) {
console . log ( " Fichier t l charg ! " ) ;

CHAPITRE 1. NODE.JS : MAIS QUOI A SERT ?


3
4

}) ;
console . log ( " Je fais d ' autres choses en attendant ... " ) ;

La requte de tlchargement est lance en premier. Ensuite, le programme fait dautres


choses (ici, il affiche un message dans la console, mais il pourrait faire nimporte quoi
dautre). Ds que le tlchargement est termin, le programme va la ligne 2 et affiche
Fichier tlcharg ! .
Mais comment a marche ? Je vois une fonction en paramtre de la fonction
request ! Cest une fonction dans une fonction, au secours ces barbus sont
fous !
Pas de panique ! Ce que vous voyez l est une fonction de callback. En JavaScript,
on peut tout fait envoyer une fonction en paramtre dune autre fonction. Cela signifie
ici : Excute cette fonction quand le tlchargement est termin.
Ici, la fonction na pas de nom. On dit que cest une fonction anonyme. Mais on
pourrait dcomposer ce code comme ceci, le rsultat serait identique :
1

// R sultat identique au code pr c dent

2
3
4
5

var callback = function ( error , response , body ) {


console . log ( " Fichier t l charg ! " ) ;
}) ;

6
7
8

request ( ' http :// www . site . com / fichier . zip ' , callback ) ;
console . log ( " Je fais d ' autres choses en attendant ... " ) ;

La fonction de callback est enregistre dans une variable. Comme toutes les fonctions,
elle nest pas excute tant quon ne la pas appele. Ensuite, on envoie cette fonction
de callback en paramtre de la fonction request() pour dire : Ds que la requte
de tlchargement est termine, appelle cette fonction de callback.
En pratique, les dveloppeurs JavaScript mettent rgulirement des fonctions anonymes directement lintrieur dautres fonctions en paramtre, comme dans mon
premier code. Cest un peu trange au dbut, mais on sy fait vite !
Je ne vois pas pourquoi a rendrait le programme plus rapide. Jai limpression
que a le rend surtout plus compliqu !
Je vous avais dit que Node.js ntait pas simple, mais le jeu en vaut la chandelle !
Vous allez comprendre pourquoi. Imaginez quon demande le tlchargement de deux
fichiers Node.js :
1
2
3

var callback = function ( error , response , body ) {


console . log ( " Fichier t l charg ! " ) ;
}) ;

4
5

10

request ( ' http :// www . site . com / fichier . zip ' , callback ) ;

POURQUOI NODE.JS EST-IL RAPIDE ?


6

request ( ' http :// www . site . com / autrefichier . zip ' , callback ) ;

Si le modle avait t bloquant, le programme aurait :


1. Lanc le tlchargement du fichier 1, et attendu quil se termine.
2. Puis lanc le tlchargement du fichier 2, et attendu quil se termine.
Or, avec Node.js, les deux tlchargements sont lancs en mme temps ! Le programme
nattend pas la fin du premier tlchargement pour passer linstruction suivante.
Du coup, le tlchargement des deux fichiers va beaucoup plus vite puisque le programme fait les deux la fois (voir figure 1.7) :

Figure 1.7 En modle non bloquant (comme Node.js), les 2 fichiers sont tlchargs
en mme temps et lensemble finit plus vite
Dans les applications web, il est courant davoir des oprations longues et bloquantes
comme :
Les appels aux bases de donnes.
Les appels des services web (ex : lAPI de Twitter).
Node.js nous vite de perdre du temps en nous permettant de faire dautres choses en
attendant que les actions longues soient termines !

En rsum
Node.js est un environnement de dveloppement qui permet de coder ct serveur en JavaScript. En ce sens il peut tre compar PHP, Python/Django,
Ruby on Rails, etc.
crire une application en Node.js demande une gymnastique desprit particulire : tout est bas sur des vnements !
Node.js est reconnu et apprci pour sa rapidit : un programme Node.js
nattend jamais inutilement sans rien faire !

11

CHAPITRE 1. NODE.JS : MAIS QUOI A SERT ?

12

Chapitre

Installer Node.js
Difficult :
Vous tes convaincus ? Vous voulez vous mettre Node.js ? Trs bien ! Nattendons pas et
installons la bte ! Dans ce chapitre, nous couvrirons linstallation pour Windows, Mac OS
X et Linux. Vous devez juste lire la section qui correspond votre systme dexploitation.
Il ny aura rien de bien difficile ici rassurez-vous.
Ensuite, nous testerons une toute premire application trs simple pour vrifier que Node.js
est bien install et fonctionne correctement. Je vous conseille de lire cette section si vous
voulez tre prts pour le prochain chapitre.

13

CHAPITRE 2. INSTALLER NODE.JS

Installation de Node.js sous Windows


Pour installer Node.js sous Windows, il suffit de tlcharger linstalleur qui est propos
sur le code web suivant :


Site de Node.js
B
.
Code web : 435670


Cliquez simplement sur le lien Install. Vous pouvez aussi vous rendre sur la page des
tlchargements pour avoir plus doptions (voir figure 2.7).

Figure 2.1 La page de tlchargement de Node.js


Vous pouvez tlcharger soit le .msi, soit le .exe (le rsultat sera le mme). Prenez la
version 64 bits si vous avez un Windows 64 bits (cas de la plupart des PC rcents).
Dans le doute, prenez la version 32 bits.
Lancez ensuite linstalleur (voir figure 2.2).
Aprs quelques crans classiques, on vous demandera ce que vous voulez installer. Je
vous invite tout laisser coch (voir figure 2.3).
Linstallation se lance ensuite. Elle ne prend que quelques secondes ! la fin, on vous
dit que Node.js est install (voir figure 2.4).
Mais o ? Comment a marche ? En fait, vous devriez avoir deux programmes installs :
14

INSTALLATION DE NODE.JS SOUS WINDOWS

Figure 2.2 Installation de Node.js

Figure 2.3 Choix des lments installer

15

CHAPITRE 2. INSTALLER NODE.JS

Figure 2.4 Linstallation est termine !

Node.js : cest linterprteur de commandes de Node.js (dont nous parlerons la fin de ce chapitre). Nous lutiliserons assez peu en pratique. Il sert
tester des commandes JavaScript.
Node.js command prompt : cest une console de Windows configure pour
reconnatre Node.js. Cest par l que vous passerez pour lancer vos programmes
Node.js, cest donc ce que nous utiliserons le plus souvent. (Voir les figures 2.5
et 2.6)

Figure 2.5 Node.js - Linterprteur Node.js sous Windows (peu utilis)

16

INSTALLATION DE NODE.JS SOUS MAC OS X

Figure 2.6 Node.js command prompt - La console Node.js (frquemment utilise)

Installation de Node.js sous Mac OS X


Si vous tes sous Mac OS X, vous pouvez cliquer sur le lien Install grce au code web
suivant (voir figure 2.7) :


Page daccueil de Node.js
B
Code web : 435670


Si vous voulez plus doptions, affichez la page de tlchargement grce au code web
suivant :


Page des tlchargements
B
Code web : 914330


Le mieux est de prendre linstalleur (fichier .pkg). Il ouvre un assistant dinstallation (voir figure 2.8) dans lequel il suffit de cliquer frntiquement sur Continuer,
Continuer, Continuer, Terminer.
Une fois linstallation termine, vous pouvez vrifier que Node.js fonctionne correctement en tapant la commande node dans la console. Ouvrez une fentre de Terminal (le
Terminal tant install par dfaut sous Mac OS X), en allant dans le Finder, section
Applications , Terminal . Je vous conseille de mettre un raccourci dans le dock !
Tapez quelques commandes comme node -v (pour avoir le numro de version) ou node
tout court pour lancer linterprteur interactif (voir figure 2.9).
Lorsque linterprteur est lanc, vous pouvez taper des commandes JavaScript et obtenir une rponse. Ici, par exemple, jai demand combien font 1 et 1.


Pour quitter linterprteur, faites Ctrl  + D  (cest la commande classique qui demande quitter un interprteur sous Linux et Mac).
17

CHAPITRE 2. INSTALLER NODE.JS

Figure 2.7 La page de tlchargement de Node.js

Figure 2.8 Linstallation de Node.js sous Mac OS X


18

INSTALLATION DE NODE.JS SOUS LINUX

Figure 2.9 Excution de Node.js dans le Terminal


Rassurez-vous, nous ncrirons pas nos programmes Node.js l-dedans ! Cela
nous sert ici surtout pour faire des tests. En pratique, nous allons crire des
fichiers .js et demander Node de les excuter. Nous verrons a un peu plus
loin.

Installation de Node.js sous Linux


Sous Linux, comme dhabitude, vous avez deux choix :
1. La mthode warrior , qui consiste tlcharger les sources et les compiler.
2. La mthode douce, qui consiste utiliser le gestionnaire de paquets de sa distribution.
L, cest une question de got. Je nai rien contre la mthode warrior , mais comme
jai en gnral moins de problmes de configuration avec la mthode douce, je prfre
passer par un gestionnaire de paquets.
Sous Ubuntu par exemple, vous devrez rentrer les commandes suivantes :
sudo
sudo
sudo
sudo

apt - get install python - software - properties python g ++ make


add - apt - repository ppa : chris - lea / node . js
apt - get update
apt - get install nodejs

Pour avoir la commande add-apt-repository il vous faudra peut-tre tlcharger


software-properties-common : sudo apt-get install software-properties-common.
19

CHAPITRE 2. INSTALLER NODE.JS


Et voil le travail ! Pour vrifier que Node est bien install, tapez quelques commandes
dans la console comme :
node -v
node

La premire affiche le numro de version de Node.js que vous avez install. La seconde
lance linterprteur interactif de Node.js. Vous pouvez y taper du code JavaScript
(essayez simplement de taper 1+1 pour voir). Pour sortir de linterprteur, faites
Ctrl + D.
Rassurez-vous, nous ncrirons pas nos programmes dans linterprteur interactif. Nous
crerons plutt des fichiers .js et demanderons Node de les excuter.
Depuis les versions les plus rcentes de Node.js, il faut savoir que NPM
est install en mme temps automatiquement. NPM est le gestionnaire de
paquets de Node.js (cest un peu lquivalent de apt, mais pour les extensions
Node.js). NPM est vraiment un outil formidable qui nous permet dtendre
les possibilits de Node.js linfini, nous le dcouvrirons un peu plus tard.

Tester Node.js avec un programme minimal


Il est temps de vrifier que Node.js fonctionne bien ! Pour commencer, nous allons
crire un tout petit programme qui se contente dafficher un message dans la console.
Ce sera loccasion de voir comment fonctionne lexcution de fichiers .js avec Node.
Pour commencer, ouvrez votre diteur de texte favori (vim, Emacs, Sublime Text,
Notepad++. . .) et rentrez le code JavaScript suivant :
console . log ( ' Bienvenue dans Node . js ! ') ;

Enregistrez votre fichier sous lextension .js. Par exemple test.js. Ensuite, ouvrez une
console dans le dossier o se trouve votre fichier test.js et entrez la commande node
test.js. Vous devriez avoir le rsultat suivant dans la console :
$ node test . js
Bienvenue dans Node . js !

Bravo, vous avez cr votre tout premier programme Node.js ! Ctait vraiment ce que
lon pouvait faire de plus simple. On a simplement demand crire un message dans
la console.
Vous avez vu que pour lancer un programme Node.js, il suffisait dindiquer le nom du
fichier .js excuter. Vous savez tout ce quil faut savoir pour le moment !
Dans le prochain chapitre, nous attaquerons les choses srieuses : nous allons crer
notre premire vraie application Node.js. Attention, a va se corser !
20

TESTER NODE.JS AVEC UN PROGRAMME MINIMAL

En rsum
Que ce soit sous Windows, Mac ou Linux, linstallation de Node.js est simple.
Une application Node.js scrit dans un fichier JavaScript lextension .js.
Une application Node.js se lance avec la commande node nomdufichier.js.

21

CHAPITRE 2. INSTALLER NODE.JS

22

Chapitre

Une premire application avec Node.js


Difficult :
Les choses srieuses commencent ! Fini de rire, nous entrons maintenant dans le vif du
sujet. Ceci est lun des chapitres les plus importants du cours car il introduit de nombreux
concepts de Node.js qui seront, pour la plupart, nouveaux pour vous. Il faudra donc lire
ce chapitre dans un environnement calme, progressivement, et ne pas hsiter le lire une
seconde fois le lendemain pour vous assurer que vous avez bien compris.
Dans ce chapitre, nous allons crer une vritable application Node.js de bout en bout.
Vous allez voir ce que bas niveau veut dire ! Nous allons en effet devoir grer tous les
rouages du serveur web qui va traiter les requtes HTTP des visiteurs et leur retourner
une page web HTML.
Ce sera pour vous loccasion dexprimenter les fameux callbacks dont je vous avais parl
dans le premier chapitre, ces fonctions qui sexcutent ds lors quun vnement survient.
Node.js en est rempli, vous ne pourrez pas y chapper !

23

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS

Des serveurs web et des threads


Je crois vous lavoir dj dit plusieurs fois, mais jai envie de le rpter une nouvelle
fois ici : Node.js est bas niveau. Tellement bas niveau que vous allez devoir faire des
choses que vous navez pas lhabitude de faire pour que votre programme fonctionne
correctement.
Quand vous crez des sites web avec PHP par exemple, vous associez le langage avec
un serveur web HTTP comme Apache ou Nginx. Chacun se rpartit les rles :
Apache gre les demandes de connexion HTTP au serveur. Cest lui qui fait en
quelque sorte la circulation et qui gre les entres/sorties.
PHP excute le code des fichiers .php et renvoie le rsultat Apache, qui se
charge son tour de lenvoyer au visiteur.
Comme plusieurs visiteurs peuvent demander une page en mme temps au serveur,
Apache se charge de les rpartir et de les excuter en parallle dans des threads
diffrents. Chaque thread utilise un processeur diffrent sur le serveur (ou un noyau
de processeur) (voir figure 3.1) :

Figure 3.1 Le serveur Apache est multithread


Avec Node.js, on nutilise pas de serveur web HTTP comme Apache. En fait, cest
nous de crer le serveur ! Gnial non ?
Node.js est monothread, contrairement Apache. Cela veut dire quil ny a quun
seul processus, une seule version du programme qui peut tourner la fois en mmoire.
Mais je croyais que Node.js tait trs rapide parce quil pouvait grer des
tonnes de requtes simultanes. Sil est monothread, il ne peut faire quune
action la fois non ?
En effet, il ne peut faire quune chose la fois et ne tourne donc que sur un noyau de
processeur. Mais il fait a de faon ultra efficace, et malgr cela, il est quand mme
24

CONSTRUIRE SON SERVEUR HTTP


beaucoup plus rapide ! Cela est d la nature oriente vnements de Node.js. Les
applications utilisant Node ne restent jamais les bras croiss sans rien faire. Ds quil
y a une action un peu longue, le programme donne de nouveau la main Node.js qui
va effectuer dautres actions en attendant quun vnement survienne pour dire que
lopration est termine. (Voir figure 3.2)

Figure 3.2 Node.js est monothread, mais il est souple grce aux vnements

Construire son serveur HTTP


Je vous propose dentrer dans le vif du sujet avec ce tout premier code Node.js :
1

var http = require ( ' http ') ;

2
3
4
5
6
7

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


res . writeHead ( 200 ) ;
res . end ( ' Salut tout le monde ! ') ;
}) ;
server . listen ( 8080 ) ;

Cest en quelque sorte le code minimal pour un projet Node.js. Placez-le dans un
fichier que vous appellerez serveur.js (par exemple).

Que fait ce code ?

Il cre un mini-serveur web qui renvoie un message Salut tout le monde dans tous les
cas, quelque soit la page demande. Ce serveur est lanc sur le port 8080 la dernire
ligne.
25

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS

Dissquons du code
Dcomposons le code :
1

var http = require ( ' http ') ;

require effectue un appel une bibliothque de Node.js, ici la bibliothque http


qui nous permet de crer un serveur web. Il existe des tonnes de bibliothques comme
celle-l, la plupart pouvant tre tlcharges avec NPM, le gestionnaire de paquets de
Node.js (nous apprendrons lutiliser plus tard).
La variable http reprsente un objet JavaScript qui va nous permettre de lancer un
serveur web. Cest justement ce quon fait avec :
1

var server = http . createServer () ;

On appelle la fonction createServer() contenue dans lobjet http et on enregistre ce


serveur dans la variable server. Vous remarquerez que la fonction createServer prend
un paramtre. . . et que ce paramtre est une fonction ! Cest pour a que linstruction
est un peu complique, puisquelle stend sur plusieurs lignes :
1
2
3
4

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


res . writeHead ( 200 ) ;
res . end ( ' Salut tout le monde ! ') ;
}) ;

Tout ce code correspond lappel createServer(). Il comprend en paramtre la


fonction excuter quand un visiteur se connecte notre site.
Notez que vous pouvez faire a en deux temps comme je vous lavais dit. La fonction
excuter est la fonction de callback. On peut la dfinir avant dans une variable
et transmettre cette variable createServer(). Ainsi, le code suivant est strictement
identique au prcdent :
1

// Code identique au pr c dent

2
3
4
5
6

var i n s t r u c t i o n s N o u v e a u V i s i t e u r = function ( req , res ) {


res . writeHead ( 200 ) ;
res . end ( ' Salut tout le monde ! ') ;
}

7
8

var server = http . createServer ( i n s t r u c t i o n s N o u v e a u V i s i t e u r ) ;

Il est trs important que vous compreniez ce principe, car Node.js ne fonctionne que
comme a. Il y a des fonctions de callback partout et, en gnral, elles sont places
lintrieur des arguments dune autre fonction comme je lai fait dans mon premier
code. Cela parat un peu dlicat lire, mais vous prendrez vite le pli, rassurez-vous.
Noubliez pas de bien fermer la fonction de callback avec une accolade, de fermer les
parenthses dappel de la fonction qui lenglobe, puis de placer le fameux point-virgule.
Cest pour a que vous voyez les symboles }); la dernire ligne de mon premier code.
La fonction de callback est donc appele chaque fois quun visiteur se connecte
notre site. Elle prend deux paramtres :
26

CONSTRUIRE SON SERVEUR HTTP


1. La requte du visiteur (req dans mes exemples) : cet objet contient toutes les
informations sur ce que le visiteur a demand. On y trouve le nom de la page
appele, les paramtres, les ventuels champs de formulaires remplis.
2. La rponse que vous devez renvoyer (res dans mes exemples) : cest cet objet
quil faut remplir pour donner un retour au visiteur. Au final, res contiendra
en gnral le code HTML de la page renvoyer au visiteur.
Ici, on effectue deux choses trs simples dans la rponse :
1
2

res . writeHead ( 200 ) ;


res . end ( ' Salut tout le monde ! ') ;

On renvoie le code 200 dans len-tte de la rponse, qui signifie au navigateur OK


tout va bien (on aurait par exemple rpondu 404 si la page demande nexistait pas).
Il faut savoir quen plus du code HTML, le serveur renvoie en gnral tout un tas de
paramtres en en-tte. Il faut connatre la norme HTTP qui indique comment clients
et serveurs doivent communiquer pour bien lutiliser. Voil encore un exemple de la
complexit due au fait que Node.js est bas niveau. Mais en mme temps, cela nous
fait comprendre tout un tas de choses.
Ensuite, on termine la rponse (avec end()) en envoyant le message de notre choix au
navigateur. Ici, on nenvoie mme pas de HTML, juste du texte brut.
Enfin, le serveur est lanc et coute sur le port 8080 avec linstruction :
1

server . listen ( 8080 ) ;

On vite dutiliser ici le port 80 qui est normalement rserv aux serveurs web
car celui-ci est peut-tre dj utilis par votre machine. Ce port 8080 sert
juste pour nos tests videmment, une fois en production il est conseill au
contraire dcouter cette fois sur le port 80, car cest cette porte ( ce port)
que vos visiteurs iront taper en arrivant sur votre serveur.

Tester le serveur HTTP


Pour tester votre premier serveur, rendez-vous dans la console et tapez :
node serveur . js

La console naffiche rien et ne rpond pas, ce qui est parfaitement normal. Ouvrez maintenant votre navigateur et rendez-vous ladresse http://localhost:8080. Vous allez
vous connecter sur votre propre machine sur le port 8080 sur lequel votre programme
Node.js est en train dcouter ! Vous devriez obtenir quelque chose ressemblant la
figure 3.3.


Pour arrter votre serveur Node.js, retournez dans la console et faites Ctrl  + C 
pour couper la commande.
27

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS

Figure 3.3 Notre premier programme Node.js saffiche dans le navigateur !

Retourner du code HTML


Rsumons ! Nous avons cr notre premire vritable application avec son serveur web
embarqu. Mais lapplication est pour linstant minimaliste :
Le message renvoy est du texte brut, il ne comporte mme pas de HTML !
Lapplication renvoie toujours le mme message, quelle que soit la page appele
(http://localhost:8080, http://localhost:8080/mapage,
http://localhost:8080/dossier/autrepage).
Pour que ce chapitre soit complet, nous allons voir comment remdier ces deux
problmes. Commenons ici par voir comment faire pour renvoyer du HTML.
Comme je vous lai dit, il y a des rgles respecter entre le client et le serveur. Ils
communiquent en se basant sur la norme HTTP invente par Tim Berners-Lee. Cette
norme est la base du web (tout comme le langage HTML qui a aussi t invent
par ce mme monsieur).
Que dit la norme HTTP ? Que le serveur doit indiquer le type de donnes quil
sapprte envoyer au client. Et oui, un serveur peut renvoyer diffrents types de
donnes :

Du texte brut : text/plain.


Du HTML : text/html.
Du CSS : text/css.
Une image JPEG : image/jpeg.
Une vido MPEG4 : video/mp4.
Un fichier ZIP : application/zip.
Etc.

Ce sont ce quon appelle les types MIME. Ils sont envoys dans len-tte de la rponse
du serveur. Vous vous souvenez comment on crit dans len-tte de la rponse avec
Node.js ? Nous avions crit ceci :
1

28

res . writeHead ( 200 ) ;

RETOURNER DU CODE HTML


Nous avions seulement indiqu le code de rponse 200 qui signifie OK, pas derreur .
Nous devons rajouter un paramtre qui indique le type MIME de la rponse. Pour
HTML, ce sera donc :
1

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

Le second paramtre est entre accolades, car on peut y envoyer plusieurs


valeurs sous forme de tableau.
Maintenant que cest fait, nous pouvons renvoyer du HTML dans la rponse !
1

res . end ( ' <p > Voici un paragraphe < strong > HTML </ strong > ! </p > ') ;

Au final, notre code ressemble donc maintenant ceci :


1

var http = require ( ' http ') ;

2
3
4
5
6
7

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


res . writeHead ( 200 , { " Content - Type " : " text / html " }) ;
res . end ( ' <p > Voici un paragraphe < strong > HTML </ strong > ! </p >
') ;
}) ;
server . listen ( 8080 ) ;

Essayez-le comme vous lavez appris, en lanant lapplication avec la commande node
dans la console et en ouvrant votre navigateur sur http://localhost:8080 (voir figure
3.4).

Figure 3.4 Un paragraphe HTML renvoy par notre appli Node.js


Votre paragraphe de texte saffiche et est bien mis en forme comme prvu !
Mais le code HTML nest pas valide non ? On na pas crit de doctype, ni la
balise <html>, ni la balise <body>.
Grmpf, vous mavez pris la main dans le sac ! Un code HTML invalide, jai honte.
Rparons a ! Cest facile, il suffit denvoyer toutes les autres balises qui manquent.
29

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS


Jusquici, nous avions toujours crit le code HTML dans res.end(). Pour
mieux dcouper le code, partir de maintenant, jutilise la commande
res.write() qui permet dcrire la rponse en plusieurs temps. a revient
au mme, mais notre code est mieux dcoupl comme a. res.end() doit
toujours tre appel en dernier pour terminer la rponse et faire en sorte que
le serveur envoie le rsultat au client.

var http = require ( ' http ') ;

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

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


res . writeHead ( 200 , { " Content - Type " : " text / html " }) ;
res . write ( ' <! DOCTYPE html > '+
' < html > '+
'
< head > '+
'
< meta charset =" utf - 8 " / > '+
'
< title > Ma page Node . js ! </ title > '+
'
</ head > '+
'
< body > '+
'
<p > Voici un paragraphe < strong > HTML </ strong > ! </p > '+
'
</ body > '+
' </ html > ') ;
res . end () ;
}) ;
server . listen ( 8080 ) ;

Mais cest atroce dcrire du HTML comme a !

On fait ce quon peut avec ce quon a ! Rappelez-vous que Node.js est bas niveau. . .
Je vous rassure, aucun dveloppeur ne samusera vraiment faire des pages web
HTML complexes comme a l-dedans. Il existe des moyens de sparer le code HTML
du code JavaScript : ce sont les systmes de templates. Cest un peu hors sujet
pour le moment, tant donn que nous commenons tout juste dcouvrir les bases
de Node.js. Mais si le sujet vous intresse, sachez quil existe des tonnes de modules
(voir le code web suivant) :


Des modules Node.js ddis
B aux templates
Code web : 272512


Le choix est immense !
30

DTERMINER LA PAGE APPELE ET LES PARAMTRES

Dterminer la page appele et les paramtres


Nous savons renvoyer du code HTML, mais pour le moment notre application renvoie
toujours la mme chose ! Comment fait-on pour crer diffrentes pages avec Node.js ?
Essayez notre petite application sur diffrentes URL. Quelque soit la page appele, la
page qui saffiche est toujours la mme !
Il faut quon sache quelle est la page demande par le visiteur. Pour linstant, vu que
nous ne faisons aucun test, notre application renvoie toujours la mme chose.
Nous allons dcouvrir comment rcuprer :
Le nom de la page demande (/mapage, /page.html, /dossier/autrepage. . .).
Les paramtres qui circulent dans lURL.

Quelle est la page demande par le visiteur ?


Pour rcuprer la page demande par le visiteur, on va faire appel un nouveau module
de Node appel url . On demande son inclusion avec :
1

var url = require ( " url " ) ;

Ensuite, il nous suffit de parser la requte du visiteur comme ceci pour obtenir le
nom de la page demande :
1

url . parse ( req . url ) . pathname ;

Voici un code trs simple qui nous permet de tester a :


1
2

var http = require ( ' http ') ;


var url = require ( ' url ') ;

3
4
5
6
7
8
9
10
11

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


var page = url . parse ( req . url ) . pathname ;
console . log ( page ) ;
res . writeHead ( 200 , { " Content - Type " : " text / plain " }) ;
res . write ( ' Bien le bonjour ') ;
res . end () ;
}) ;
server . listen ( 8080 ) ;

Excutez ce script et lancez votre navigateur ladresse http://localhost:8080 pour


commencer. Retournez ensuite dans la console. Nous y loggons le nom de la page
demande. Vous devriez y voir :
/
/ favicon . ico

Je nai charg que la page daccueil, pourquoi est-ce que je vois /favicon.ico ?

31

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS


La plupart des navigateurs font en ralit une seconde requte pour rcuprer licne
du site (la favicon quon voit dans les onglets en gnral). Cest normal, ne vous en
proccupez pas.
Essayez maintenant de charger de fausses pages de votre site pour voir ce que a
fait.
/ testpage
/ favicon . ico
/ un / long / chemin /
/ favicon . ico
/ faussepage . html
/ favicon . ico

Si on omet les favicon.ico qui viennent un peu polluer la console, on voit que jai essay
de charger les pages suivantes :
http://localhost:8080/testpage
http://localhost:8080/un/long/chemin
http://localhost:8080/faussepage.html
Vous pouvez retrouver la page directement grce au code web suivant :


Page faussepage
B
Code web : 528764


Et alors ? Mon site renvoie toujours la mme chose quelle que soit la page
appele !
En effet. Mais il suffit dcrire une condition, et le tour est jou !
1
2

var http = require ( ' http ') ;


var url = require ( ' url ') ;

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

32

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


var page = url . parse ( req . url ) . pathname ;
console . log ( page ) ;
res . writeHead ( 200 , { " Content - Type " : " text / plain " }) ;
if ( page == '/ ') {
res . write ( ' Vous tes l \ ' accueil , que puis - je pour
vous ? ') ;
}
else if ( page == '/ sous - sol ') {
res . write ( ' Vous tes dans la cave vins , ces
bouteilles sont moi ! ') ;
}
else if ( page == '/ etage / 1 / chambre ') {
res . write ( 'H ho , c \ ' est priv ici ! ') ;
}
res . end () ;

DTERMINER LA PAGE APPELE ET LES PARAMTRES


18
19

}) ;
server . listen ( 8080 ) ;

Allez un petit dfi pour vous entraner : faites en sorte dafficher un message derreur si
le visiteur demande une page inconnue. Et noubliez pas de renvoyer un code derreur
404 !

Quels sont les paramtres ?


Les paramtres sont envoys la fin de lURL, aprs le chemin du fichier. Prenez cette
URL par exemple : http://localhost:8080/page?prenom=Robert&nom=Dupont.
Les paramtres sont contenus dans la chane ?prenom=Robert&nom=Dupont. Pour rcuprer cette chane, il suffit de faire appel :
1

url . parse ( req . url ) . query

Le problme, cest quon vous renvoie toute la chane sans dcouper au pralable les
diffrents paramtres. Heureusement, il existe un module Node.js qui sen charge pour
nous : querystring !
Incluez ce module :
1

var querystring = require ( ' querystring ') ;

Vous pourrez ensuite faire :


1

var params = querystring . parse ( url . parse ( req . url ) . query ) ;

Vous disposerez alors dun tableau de paramtres params. Pour rcuprer le paramtre
prenom par exemple, il suffira dcrire : params[prenom].
Amusons-nous avec un code complet qui affiche votre prnom et votre nom (pourvu
que ceux-ci soient dfinis !) :
1
2
3

var http = require ( ' http ') ;


var url = require ( ' url ') ;
var querystring = require ( ' querystring ') ;

4
5
6
7
8
9
10
11
12
13
14
15
16

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


var params = querystring . parse ( url . parse ( req . url ) . query ) ;
res . writeHead ( 200 , { " Content - Type " : " text / plain " }) ;
if ( ' prenom ' in params && ' nom ' in params ) {
res . write ( ' Vous vous appelez ' + params [ ' prenom '] + ' '
+ params [ ' nom ' ]) ;
}
else {
res . write ( ' Vous devez bien avoir un pr nom et un nom ,
non ? ') ;
}
res . end () ;
}) ;
server . listen ( 8080 ) ;

33

CHAPITRE 3. UNE PREMIRE APPLICATION AVEC NODE.JS


Essayez daller sur http://localhost:8080?prenom=Robert&nom=Dupont pour voir,
puis changez le prnom et le nom pour les remplacer par les vtres !
Deux petites prcisions par rapport ce code : prenom in params me
permet en JavaScript de tester si le tableau contient bien une entre
prenom. Sil manque un paramtre, je peux alors afficher un message derreur (sinon mon script aurait affich undefined la place). Par ailleurs,
vous constaterez que je ne vrifie pas la page qui est appele. Ce code
fonctionne aussi bien que lon soit sur http://localhost:8080 ou sur
http://localhost:8080/pageimaginaire. Il faudrait combiner ce code
et le prcdent pour grer la fois la page et les paramtres.

Schma rsum
Rsumons ce que nous venons dapprendre dans un seul et unique schma (voir figure
3.5) avant de terminer.

Figure 3.5 Rcuprer lURL et les paramtres avec Node.js

En rsum
Avec Node.js, votre application doit grer le serveur web (quivalent dApache)
en plus de ses propres fonctionnalits. Elle doit notamment dterminer le nom
de la page demande et ses paramtres pour savoir ce quelle doit renvoyer au
visiteur.
Les bibliothque de Node.js sont appeles des modules et on les charge avec
require()
Avec Node.js, on envoie frquemment des fonctions en paramtre dautres fonctions. Cela permet dindiquer la fonction suivante appeler lorsquune tche est
termine.
Votre application devra gnralement renvoyer du HTML au navigateur du
visiteur avec la mthode write().

34

Deuxime partie

Structurer son application


Node.js

35

Chapitre

Les vnements
Difficult :
Node.js est un environnement de dveloppement JavaScript bas sur les vnements.
Je vous ai montr dans le premier chapitre ce que a signifie : il y a un seul thread mais
aucune opration nest bloquante. Ainsi, les oprations un peu longues (chargement dun
fichier, tlchargement dune page web, dmarrage dun serveur web. . .) sont lances en
tche de fond et une fonction de callback est appele quand lopration est termine.
Les vnements sont la base de Node.js. Cest ce qui fait que Node.js est puissant mais
aussi un peu plus difficile apprhender puisque il nous impose de coder avec beaucoup de
fonctions de callback. Je vous propose de rentrer ici dans les dtails du fonctionnement
des vnements Node.js. Nous verrons en particulier comment on peut couter et
crer des vnements. Tout dveloppeur Node.js qui se respecte doit savoir le faire,
alors au boulot !

37

CHAPITRE 4. LES VNEMENTS

couter des vnements


Surprise ! Vous savez dj couter des vnements en JavaScript. Vous nallez pas
me faire croire que vous navez jamais utilis une bibliothque comme jQuery pour
couter des vnements sur votre page web !
Par exemple :
1

$ ( " canvas " ) . on ( " mouseleave " , function () { ... }) ;

Avec ce genre dinstruction, vous demandez excuter une fonction de callback


quand la souris sort dun lment <canvas> de la page. On dit que vous attachez
lvnement au DOM de la page.
Avec Node.js, le principe est exactement le mme. Un trs grand nombre dobjets
Node.js mettent des vnements. Leur particularit ? Ils hritent tous dun objet
EventEmitter fourni par Node.
Prenons par exemple le module http que nous avons utilis pour crer notre serveur
web. Il comprend un objet Server qui met des vnements. La figure 4.1 est un extrait
du document que vousretrouverez grce au code web suivant :


La doc
B
Code web : 438864

Figure 4.1 La doc de Node.js indique les vnements que les objets mettent
Comment couter ces vnements ? Supposons par exemple quon souhaite couter
lvnement close qui survient quand le serveur est arrt. Il suffit de faire appel la
mthode on() et dindiquer :
Le nom de lvnement que vous coutez (ici close).
La fonction de callback appeler quand lvnement survient.
Exemple :
1
2
3

38

server . on ( ' close ' , function () {


// Faire quelque chose quand le serveur est arr t
})

COUTER DES VNEMENTS


Je vous propose un exemple concret et complet. On va lancer un serveur et larrter
juste aprs. On coute lvnement close qui survient lorsque le serveur est arrt. On
affiche un message dans la console quand le serveur sapprte sarrter.
1

var http = require ( ' http ') ;

2
3
4
5
6

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


res . writeHead ( 200 ) ;
res . end ( ' Salut tout le monde ! ') ;
}) ;

7
8
9
10

server . on ( ' close ' , function () { // On coute l ' v nement close


console . log ( ' Bye bye ! ') ;
})

11
12

server . listen ( 8080 ) ; // D marre le serveur

13
14

server . close () ; // Arr te le serveur . D clenche l ' v nement


close

Mais au fait. . . createServer() comprend une fonction de callback lui aussi.


Pourquoi on nutilise pas on() ici ?
Bien vu ! En fait, cest une contraction de code. Lisez la section "CreateServer" sur
la doc indique sur le code web prcdent. Elle dit que la fonction de callback quon
lui envoie en paramtre est automatiquement ajoute lvnement request !
Donc ce code :
1

var server = http . createServer ( function ( req , res ) { }) ;

. . . peut tre rcrit comme ceci de faon plus dtaille :


1
2
3

// Code quivalent au pr c dent


var server = http . createServer () ;
server . on ( ' request ' , function ( req , res ) { }) ;

Bref, les vnements sont partout, vous ne pouvez pas y chapper ! Certains sont
simplement un peu masqus comme cest le cas ici, mais il est important de savoir
ce qui se passe derrire.
Vous pouvez couter plusieurs fois un mme vnement. Faites deux fois
appel la fonction on() pour le mme vnement : les deux fonctions de
callback seront appeles quand lvnement aura lieu.

39

CHAPITRE 4. LES VNEMENTS

mettre des vnements


Si vous voulez mettre des vnements vous aussi, cest trs simple : incluez le
module EventEmitter et crez un objet bas sur EventEmitter.
1

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

2
3

var jeu = new EventEmitter () ;

Ensuite, pour mettre un vnement dans votre code, il suffit de faire appel emit()
depuis votre objet bas sur EventEmitter. Indiquez :
Le nom de lvnement que vous voulez gnrer (ex : gameover). vous de le
choisir.
Un ou plusieurs ventuels paramtres passer (facultatif).
Ici, je gnre un vnement gameover et jenvoie un message celui qui rceptionnera
lvnement via un paramtre :
1

jeu . emit ( ' gameover ' , ' Vous avez perdu ! ') ;

Celui qui veut couter lvnement doit ensuite faire :


1

jeu . on ( ' gameover ' , function ( message ) { }) ;

Voici un code complet pour tester lmission dvnements :


1

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

2
3

var jeu = new EventEmitter () ;

4
5
6
7

jeu . on ( ' gameover ' , function ( message ) {


console . log ( message ) ;
}) ;

8
9

jeu . emit ( ' gameover ' , ' Vous avez perdu ! ') ;

Je ladmets, cest un peu trop simple. Ce code se contente dmettre un vnement.


Dans la ralit, les vnements seront mis depuis des fonctions imbriques dans
dautres fonctions, cest de l que Node.js tire toute sa richesse.
Comme vous le voyez, le principe nest pas franchement compliqu comprendre !
Noubliez pas que vous pouvez envoyer autant de paramtres que ncessaire la fonction de callback. mettez simplement plus de paramtres :
1

jeu . emit ( ' nouveaujoueur ' , ' Mario ' , 35 ) ; // Envoie le nom d ' un
nouveau joueur qui arrive et son ge

En rsum
Toutes les applications Node.js sont bases sur un mcanisme dvnements,
qui dtermine quelle est la prochaine fonction appeler.
40

METTRE DES VNEMENTS


Avec la mthode on(), vous pouvez couter un vnement et indiquer quelle
fonction doit tre appele lorsque lvnement survient.
Avec la mthode emit() vous pouvez crer votre propre vnement et donc
provoquer le dclenchement des fonctions qui attendent cet vnement.

41

CHAPITRE 4. LES VNEMENTS

42

Chapitre

Les modules Node.js et NPM


Difficult :
Croyez-le ou non, le noyau de Node.js est tout petit. A la base, Node.js ne sait en fait pas
faire grand chose. Pourtant, Node.js est trs riche grce son extensibilit. Ces extensions
de Node.js sont appeles modules.
Il existe des milliers de modules qui offrent des fonctionnalits varies : de la gestion des
fichiers uploads la connexion aux bases de donnes MySQL ou Redis, en passant
par des frameworks, des systmes de templates et la gestion de la communication temps
rel avec le visiteur ! Il y a peu prs tout ce dont on peut rver et de nouveaux modules
apparaissent chaque jour.
Nous allons commencer par voir comment sont grs les modules par Node.js et nous
verrons que nous pouvons facilement en crer un nous aussi. Puis, nous dcouvrirons NPM
(Node Package Manager), loutil indispensable qui vous permet de tlcharger facilement
tous les modules de la communaut Node.js ! Enfin, je vous montrerai comment accder
la gloire ternelle en publiant votre module sur NPM.

43

CHAPITRE 5. LES MODULES NODE.JS ET NPM

Crer des modules


Vous souvenez-vous de cette ligne ?
1

var http = require ( ' http ') ;

Elle tait tout au dbut de notre premier code. Je vous avais dit que ctait un appel
la bibliothque http de Node.js (ou devrais-je dire au module http ).
Lorsque lon effectue cela, Node.js va chercher sur notre disque un fichier appel
http.js. De mme, si on demande le module url , Node.js va rechercher un fichier
appel url.js.
1
2

var http = require ( ' http ') ; // Fait appel http . js


var url = require ( ' url ') ; // Fait appel url . js

O sont ces fichiers .js ? Je ne les vois pas !

Ils sont quelque part bien au chaud sur votre disque, leur position ne nous intresse pas.
tant donn quils font partie du noyau de Node.js, ils sont tout le temps disponibles.
Les modules sont donc de simples fichiers .js. Si nous voulons crer un module,
disons le module test , nous devons crer un fichier test.js dans le mme dossier
et y faire appel comme ceci :
1

var test = require ( ' ./ test ') ; // Fait appel test . js ( m me


dossier )

Il ne faut pas mettre lextension .js dans le require() !

Cest un chemin relatif. Si le module se trouve dans le dossier parent, nous pouvons
linclure comme ceci :
1

var test = require ( ' ../ test ') ; // Fait appel test . js ( dossier
parent )

Et si je ne veux pas mettre de chemin relatif ? Je ne peux pas juste faire


require(test) ?
Si vous pouvez ! Il faut mettre votre fichier test.js dans un sous-dossier appel
node_modules. Cest une convention de Node.js :
1

44

var test = require ( ' test ') ; // Fait appel test . js ( sous dossier node_modules )

CRER DES MODULES


La figure 5.1 rsume tout a.

Figure 5.1 Node.js sait o chercher les modules


Notez que si le dossier node_modules nexiste pas, Node.js ira chercher un dossier qui
a le mme nom plus haut dans larborescence. Ainsi, si votre projet se trouve dans le
dossier : /home/mateo21/dev/nodejs/projet, il ira chercher un dossier nomm :
/home/mateo21/dev/nodejs/projet/node_modules, et si ce dossier nexiste
pas il ira le chercher dans. . .
. . . /home/mateo21/dev/nodejs/node_modules, et si ce dossier nexiste pas il
ira le chercher dans. . .
. . . /home/mateo21/dev/node_modules, et ainsi de suite !

quoi ressemble le code des fichiers .js des modules ?

Cest du code JavaScript tout ce quil y a de plus classique. Vous y crez des fonctions.
Une seule particularit : vous devez exporter les fonctions que vous voulez que
dautres personnes puissent rutiliser.
Testons cela ! Nous allons crer un module tout bte qui sait dire Bonjour ! et Bye
bye ! . Crez un fichier monmodule.js avec le code suivant :
1
2
3

var direBonjour = function () {


console . log ( ' Bonjour ! ') ;
}

45

CHAPITRE 5. LES MODULES NODE.JS ET NPM


4
5
6
7

var direByeBye = function () {


console . log ( ' Bye bye ! ') ;
}

8
9
10

exports . direBonjour = direBonjour ;


exports . direByeBye = direByeBye ;

Le dbut du fichier ne contient rien de nouveau. Nous crons des fonctions que nous
plaons dans des variables. Do le var direBonjour = function().
Ensuite, et cest la nouveaut, nous exportons ces fonctions pour quelles soient utilisables de lextrieur : exports.direBonjour = direBonjour;. Notez dailleurs quon
aurait aussi pu faire directement :
1

exports . direBonjour = function () { ... };

Toutes les fonctions que vous nexportez pas dans votre fichier de module
resteront prives. Elles ne pourront pas tre appeles de lextrieur. En revanche, elles pourront tout fait tre utilises par dautres fonctions de votre
module.
Maintenant, dans le fichier principal de votre application (ex : app.js), vous pouvez
faire appel ces fonctions issues du module !
1

var monmodule = require ( ' ./ monmodule ') ;

2
3
4

monmodule . direBonjour () ;
monmodule . direByeBye () ;

require() renvoie en fait un objet qui contient les fonctions que vous avez exportes
dans votre module. Nous stockons cet objet dans une variable du mme nom monmodule
(mais on aurait pu lui donner nimporte quel autre nom), comme la figure 5.2.
Voil, vous savez tout ! Tous les modules de Node.js sont bass sur ce principe trs
simple. Cela vous permet de dcouper votre projet en plusieurs petits fichiers pour
rpartir les rles.

Utiliser NPM pour installer des modules


Je vous ai parl en introduction de NPM, le Node Package Manager (voir le code web
suivant) :


NPM
B
Code web : 953624


Je vous ai dit que ctait un moyen (formidable) dinstaller de nouveaux modules
dvelopps par la communaut.
46

UTILISER NPM POUR INSTALLER DES MODULES

Figure 5.2 Exportation dune fonction


Imaginez que NPM est un peu lquivalent dapt-get sous Linux pour installer des
programmes. Une simple commande et le module est tlcharg et install ! En plus,
NPM gre les dpendances. Cela signifie que, si un module a besoin dun autre module
pour fonctionner, NPM ira le tlcharger automatiquement !
NPM est trs actif, il y a plusieurs dizaines de milliers de modules disponibles, et on
compte plusieurs millions de tlchargements par semaine ! Vous y trouverez sans doute
votre bonheur.
Comme le dit le site web de NPM, il est aussi simple dinstaller de nouveaux modules
que de publier ses propres modules. Cest en bonne partie ce qui explique le grand
succs de Node.js.
Comment trouver un module l-dedans ? Autant chercher une aiguille dans
une botte de foin !
Cest assez facile en fait. Je vais vous montrer plusieurs moyens de trouver des modules !

Trouver un module
Si vous savez ce que vous cherchez, le site web de NPM vous permet de faire une recherche. Mais NPM, cest avant tout une commande ! Vous pouvez faire une recherche
dans la console, comme ceci :
npm search postgresql

Ce qui aura pour effet de rechercher tous les modules en rapport avec la base de donnes
PostgreSQL.
Si comme moi vous voulez flner un peu et que vous ne savez pas trop ce que vous
recherchez, vous aimerez srement le site Nodetoolbox (voir le code web suivant) :
47

CHAPITRE 5. LES MODULES NODE.JS ET NPM



Le site nodetoolbox
B
Code web : 537828


Il organise les modules par thmatique (voir figure 5.3).

Figure 5.3 Le site Node Toolbox est un bon moyen de dcouvrir de nouveaux modules

Installer un module
Pour installer un module, rien de plus simple. Placez-vous dans le dossier de votre
projet et tapez :
npm install nomdumodule

Le module sera install localement spcialement pour votre projet. Si vous avez un
autre projet, il faudra donc relancer la commande pour linstaller nouveau pour cet
autre projet. Cela vous permet dutiliser des versions diffrentes dun mme module en
fonction de vos projets.
Allez faisons un test. On va installer le module markdown qui permet de convertir du
code markdown en HTML.
npm install markdown

NPM va tlcharger automatiquement la dernire version du module et il va la placer


dans un sous-dossier node_modules. Vrifiez donc bien que vous tes dans le dossier
de votre projet Node.js avant de lancer cette commande !
48

UTILISER NPM POUR INSTALLER DES MODULES


Une fois que cest fait, vous avez accs aux fonctions offertes par le module markdown . Lisez la documentation du module pour savoir comment lutiliser (voir code
web suivant) :


Doc du module
B
Code web : 353493


On nous apprend quil faut faire appel lobjet markdown lintrieur du module et
quon peut appeler la fonction toHTML pour traduire du Markdown en HTML.
Essayons a :
1

var markdown = require ( ' markdown ') . markdown ;

2
3

console . log ( markdown . toHTML ( ' Un paragraphe en ** markdown ** ! ') )


;

Cela affichera dans la console :


<p > Un paragraphe en < strong > markdown </ strong > ! </p >

Ne soyez pas surpris par le require(markdown).markdown. La doc du


module nous dit que les fonctions sont dans lobjet markdown, donc on va
chercher directement cet objet au sein du module.

Linstallation locale et linstallation globale


NPM installe les modules localement pour chaque projet. Cest pour cela quil cre
un sous-dossier node_modules lintrieur de votre projet. Si vous utilisez le mme
module dans trois projets diffrents, il sera tlcharg et copi trois fois. Cest normal,
cela nous permet de grer les diffrences de versions. Cest donc une bonne chose.
Par contre, il faut savoir que NPM permet aussi dinstaller des modules globaux.
Cela ne nous sert que dans de rares cas o le module fournit des excutables (et pas
juste des fichiers .js).
Cest le cas de notre module markdown par exemple. Pour linstaller globalement,
on va ajouter le paramtre -g la commande npm :
npm install markdown -g

Vous aurez alors accs un excutable md2html dans votre console :


echo Hello * World *! | md2html

Les modules installs globalement ne peuvent pas tre inclus dans vos projets
Node.js avec require() ! Ils servent juste fournir des commandes supplmentaires dans la console. Si vous voulez les utiliser en JavaScript, vous
devez donc aussi les installer normalement (sans le -g) en local.
49

CHAPITRE 5. LES MODULES NODE.JS ET NPM

Mettre jour les modules


Avec une simple commande :
npm update

NPM va chercher sur les serveurs sil y a de nouvelles versions des modules, puis
mettre jour les modules installs sur votre machine (en veillant ne pas casser la
compatibilit) et il supprimera les anciennes versions. Bref, cest la commande magique.

Dclarer et publier son module


Si votre programme a besoin de modules externes, vous pouvez les installer un un
comme vous venez dapprendre le faire, mais vous allez voir que a va vite devenir
assez compliqu maintenir. Cest dautant plus vrai si vous utilisez de nombreux
modules. Comme ces modules voluent de version en version, votre programme pourrait
devenir incompatible suite une mise jour dun module externe !
Heureusement, on peut rgler tout a en dfinissant les dpendances de notre programme dans un simple fichier JSON. Cest un peu la carte didentit de notre
application.
Crez un fichier package.json dans le mme dossier que votre application. Commenons simplement avec ce code :
1

2
3
4
5
6
7

" name " : " mon - app " ,


" version " : " 0 . 1 . 0 " ,
" dependencies " : {
" markdown " : " ~ 0 . 4 "
}

Ce fichier JSON contient 3 paires cl-valeur :


name : cest le nom de votre application. Restez simple, vitez espaces et accents.
version : cest le numro de version de votre application. Il est compos dun
numro de version majeure, de version mineure et de patch. Jy reviens juste
aprs.
dependencies : cest un tableau listant les noms des modules dont a besoin
votre application pour fonctionner ainsi que les versions compatibles.
Le fichier peut tre beaucoup plus complet, je ne vous ai montr ici que les
valeurs essentielles. Pour tout connatre sur le fonctionnement de ce fichier
package.json, je vous recommande de consulter la page indique dans le
code web suivant.)
50

DCLARER ET PUBLIER SON MODULE


Cheat sheet
B
Code web : 967025

Le fonctionnement des numros de version


Pour bien grer les dpendances et savoir mettre jour le numro de version
de son application, il faut savoir comment fonctionnent les numros de version avec
Node.js. Il y a pour chaque application :
Un numro de version majeure. En gnral on commence 0 tant que lapplication nest pas considre comme mature. Ce numro change trs rarement,
uniquement quand lapplication a subi des changements trs profonds.
Un numro de version mineure. Ce numro est chang chaque fois que
lapplication est un peu modifie.
Un numro de patch. Ce numro est chang chaque petite correction de
bug ou de faille. Les fonctionnalits de lapplication restent les mmes entre les
patchs, il sagit surtout doptimisations et de corrections indispensables.
La figure 5.4 rcapitule tout ceci :

Figure 5.4 Les numros de version dune application Node.js


Ici, jai donc choisi de commencer numroter mon application la version 0.1.0 (on
aurait aussi pu commencer 1.0.0 mais cela aurait t prtentieux).
Si je corrige un bug, lapplication passera la version 0.1.1 et il me faudra mettre
jour ce numro dans le fichier package.json.
Si jamliore significativement mon application, elle passera la version 0.2.0,
puis 0.3.0 et ainsi de suite.
Le jour o je considre quelle a atteint un jalon important, et quelle est mature,
je pourrai la passer en version 1.0.0.
51

CHAPITRE 5. LES MODULES NODE.JS ET NPM

La gestion des versions des dpendances


Cest vous dindiquer avec quelles versions de ses dpendances votre application
fonctionne. Si votre application dpend du module markdown v0.3.5 trs prcisment,
vous crirez :
" dependencies " : {
" markdown " : " 0 . 3 . 5 " // Version 0 . 3 . 5 uniquement
}

1
2
3

Si vous faites un npm update pour mettre jour les modules externes, markdown ne
sera jamais mis jour (mme si lapplication passe en version 0.3.6). Vous pouvez
mettre un tilde (~) devant le numro de version pour autoriser les mises jour jusqu
la prochaine version mineure :
" dependencies " : {
" markdown " : " ~ 0 . 3 . 5 " // OK pour les versions 0 . 3 .5 , 0 . 3 .6 ,
0 . 3 .7 , etc . jusqu ' la version 0 . 4 . 0 non incluse
}

1
2
3

Si vous voulez, vous pouvez ne pas indiquer de numro de patch. Dans ce cas, les
modules seront mis jour mme si lapplication change de version mineure :
" dependencies " : {
" markdown " : " ~ 0 . 3 " // OK pour les versions 0 . 3 .X , 0 . 4 .X , 0 .
5 . X jusqu ' la version 1 . 0 . 0 non incluse
}

1
2
3

Attention nanmoins : entre deux versions mineures, un module peut changer suffisamment et votre application pourrait tre incompatible. Je recommande daccepter
uniquement les mises jour de patch, cest le plus sr.

Publier un module
Avec Node.js, vous pouvez crer une application pour vos besoins, mais vous pouvez
aussi crer des modules qui offrent des fonctionnalits. Si vous pensez que votre module
pourrait servir dautres personnes, nhsitez pas le partager ! Vous pouvez trs
facilement le publier sur NPM pour que dautres personnes puissent linstaller leur
tour.
Je rappelle quun module nest rien dautre quune application Node.js qui
contient des instructions exports pour partager des fonctionnalits.
Commencez par vous crer un compte utilisateur sur npm :
npm adduser

Une fois que cest fait, placez-vous dans le rpertoire de votre projet publier. Vrifiez
que vous avez :
52

DCLARER ET PUBLIER SON MODULE


Un fichier package.json qui dcrit votre module (au moins son nom, sa version
et ses dpendances).
Un fichier README.md (crit en markdown) qui prsente votre module de
faon un peu dtaille. Nhsitez pas y inclure un mini-tutoriel expliquant
comment utiliser votre module !
Il ne vous reste plus qu faire :
npm publish

Et voil, cest fait !


Il ne vous reste plus qu parler de votre module autour de vous, le prsenter sur les
mailing-lists de Node.js. . . Les portes de la gloire des geeks barbus vous attendent !
(Voir figure 5.5)

Figure 5.5 Votre module est publi, vous la gloire !

En rsum
Vous pouvez crer des modules Node.js pour mieux dcoupler votre code et
viter de tout crire dans un seul et mme fichier.
Vous appellerez vos modules avec require() comme vous le faites pour les
modules officiels de Node.js.
Toutes les fonctions dans le fichier de module qui peuvent tre appeles depuis
lextrieur doivent tre exportes avec la commande exports.
NPM est le gestionnaire de modules de Node.js. Comparable apt-get
et aptitude sous Linux / Debian, il permet dajouter de nouveaux modules
cods par la communaut en un clin dil.
Les modules tlchargs avec NPM sont par dfaut installs localement dans un
sous-dossier node_modules de votre application.
Lextension -g permet dinstaller un module globalement pour tout votre ordinateur. Elle nest utile que pour certains modules prcis.
Vous pouvez diffuser vos propres modules au reste de la communaut en crant
53

CHAPITRE 5. LES MODULES NODE.JS ET NPM


un fichier package.json, un README.md et avec un simple appel npm publish .

54

Chapitre

Le framework Express.js
Difficult :
Tout coder la main, a va cinq minutes. Cela peut tre utile dans certains cas prcis,
mais la plupart du temps, on aime avoir des outils disposition pour aller plus vite. Cest
pour cela quon a invent les bibliothques puis les frameworks, qui sont des sortes de
super-bibliothques.

55

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS


Si vous flnez un peu sur NPM, vous allez vite voir quil existe un module plbiscit :
Express.js . Il sagit en fait dun micro-framework pour Node.js. Il vous fournit
des outils de base pour aller plus vite dans la cration dapplications Node.js.
Mais attention : nallez pas comparer Express.js avec des poids lourds tels Django
ou Symfony2 ! Ceux-ci vous offrent des fonctionnalits trs compltes et puissantes
(comme la gnration dinterfaces dadministration), ce qui nest pas vraiment le cas
dExpress. Pourquoi ? Parce que nous partons de loin avec Node.js. Express vous
permet donc dtre un peu moins bas niveau et de grer par exemple plus facilement
les routes (URLs) de votre application et dutiliser des templates. Rien que a sera
dj une petite rvolution pour nous !
Pour suivre ce chapitre, crez-vous un dossier pour faire une application de test Node.js.
Installez-y Express avec la commande npm install express.

Les routes
Nous avons vu quel point il tait fastidieux de vrifier lURL demande avec Node.js.
On aboutissait du bon vieux code spaghetti du type :
1
2
3
4
5
6
7
8
9

if ( page == '/ ') {


// ...
}
else if ( page == '/ sous - sol ') {
// ...
}
else if ( page == '/ etage / 1 / chambre ') {
// ...
}

Lorsque lon cre des applications web, on manipule des routes comme ici. Ce sont les
diffrentes URLs auxquelles notre application doit rpondre.
La gestion des routes est un sujet important qui doit tre trait avec srieux. Si
vous avez dj manipul des frameworks comme Django ou Symfony2, vous voyez
certainement ce que je veux dire. Sinon, retenez juste ceci : bien grer les URLs de
son site est important, surtout lorsque celui-ci grossit. Et Express nous aide faire
cela correctement.

Routes simples
Voici une application trs basique utilisant Express pour commencer :
1

var express = require ( ' express ') ;

2
3

var app = express () ;

4
5
6

56

app . get ( '/ ' , function ( req , res ) {


res . setHeader ( ' Content - Type ' , ' text / plain ') ;

LES ROUTES
7
8

}) ;

res . end ( ' Vous tes l \ ' accueil ') ;

9
10

app . listen ( 8080 ) ;

Noubliez pas de faire npm install express pour que ce code fonctionne !

Vous commencez par demander linclusion dExpress et vous crez un objet app en
appelant la fonction express().
Ensuite, il vous suffit dindiquer les diffrentes routes (les diffrentes URLs) laquelle
votre application doit rpondre. Ici, jai cr une seule route, la racine / . Une
fonction de callback est appele lorsque quelquun demande cette route.
Ce systme est beaucoup mieux conu que nos if imbriqus. On peut crire autant de
routes quon le souhaite de cette faon :
1
2
3
4

app . get ( '/ ' , function ( req , res ) {


res . setHeader ( ' Content - Type ' , ' text / plain ') ;
res . end ( ' Vous tes l \ ' accueil , que puis - je pour vous ? ') ;
}) ;

5
6
7
8
9

app . get ( '/ sous - sol ' , function ( req , res ) {


res . setHeader ( ' Content - Type ' , ' text / plain ') ;
res . end ( ' Vous tes dans la cave vins , ces bouteilles sont
moi ! ') ;
}) ;

10
11
12
13
14

app . get ( '/ etage / 1 / chambre ' , function ( req , res ) {


res . setHeader ( ' Content - Type ' , ' text / plain ') ;
res . end ( 'H ho , c \ ' est priv ici ! ') ;
}) ;

Si vous voulez grer les erreurs 404, vous devez inclure les lignes suivantes la fin de
votre code obligatoirement (juste avant app.listen) :
1

// ... Tout le code de gestion des routes ( app . get ) se trouve


au - dessus

2
3
4
5
6

app . use ( function ( req , res , next ) {


res . setHeader ( ' Content - Type ' , ' text / plain ') ;
res . send ( 404 , ' Page introuvable ! ') ;
}) ;

7
8

app . listen ( 8080 ) ;

Ne vous proccupez pas trop pour linstant de la syntaxe et des paramtres, nous y
reviendrons un peu plus tard. Nous apprenons juste grer les routes avec Express
pour le moment.
57

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS


Express vous permet de chaner les appel get() et use() :
1

app . get ( '/ ' , function ( req , res ) {

2
3
4

})
. get ( '/ sous - sol ' , function ( req , res ) {

5
6
7

})
. get ( '/ etage / 1 / chambre ' , function ( req , res ) {

8
9
10

})
. use ( function ( req , res , next ) {

11
12

}) ;

Cela revient faire app.get().get().get(). . . Cela fonctionne parce que ces fonctions
se renvoient lune lautre lobjet app, ce qui nous permet de raccourcir notre code.
Ne soyez donc pas tonns si vous voyez des codes utilisant Express crits sous cette
forme.

Routes dynamiques
Express vous permet de grer des routes dynamiques, cest--dire des routes dont
certaines portions peuvent varier. Vous devez crire :nomvariable dans lURL de la
route, ce qui aura pour effet de crer un paramtre accessible depuis req.params.nomvariable.
Dmonstration :
1
2
3
4

app . get ( '/ etage /: etagenum / chambre ' , function ( req , res ) {
res . setHeader ( ' Content - Type ' , ' text / plain ') ;
res . end ( ' Vous tes la chambre de l \ ' tage n ' + req .
params . etagenum ) ;
}) ;

Cela vous permet de crer de belles URLs et vous vite davoir passer par le suffixe
("?variable=valeur") pour grer des variables. Ainsi, toutes les routes suivantes sont
valides :

/etage/1/chambre
/etage/2/chambre
/etage/3/chambre
/etage/nawak/chambre
Comment a, on peut mettre nimporte quoi ? Comment fait-on pour imposer
la prsence dun nombre ?

Le visiteur peut en effet crire nimporte quoi dans lURL. Cest donc vous de vrifier
dans votre fonction de callback que le paramtre est bien un nombre et de renvoyer
une erreur (ou une 404) si ce nest pas le cas.
58

LES TEMPLATES

Les templates
Jusquici, nous avions renvoy le code HTML directement en JavaScript. Cela nous
avait donn du code lourd et dlicat maintenir qui ressemblait ceci :
1
2
3
4
5
6
7
8
9
10

res . write ( ' <! DOCTYPE html > '+


' < html > '+
'
< head > '+
'
< meta charset =" utf - 8 " / > '+
'
< title > Ma page Node . js ! </ title > '+
'
</ head > '+
'
< body > '+
'
<p > Voici un paragraphe < strong > HTML </ strong > ! </p > '+
'
</ body > '+
' </ html > ') ;

Horrible, nest-ce pas ? Heureusement, Express nous permet dutiliser des templates
pour sortir de cet enfer. Les templates sont en quelque sorte des langages faciles
crire qui nous permettent de produire du HTML et dinsrer au milieu du contenu
variable.
PHP lui-mme est en ralit un langage de template qui nous permet de faire ceci :
1

<p > Vous tes le visiteur n <? php echo $numvisiteur ; ? > </p >

Il existe beaucoup dautres langages de templates, comme Twig, Smarty, Haml,


JSP, Jade, EJS, etc. Express vous permet dutiliser la plupart dentre eux, chacun
ayant son lot davantages et dinconvnients. En gnral, ils grent tous lessentiel,
savoir les variables, les conditions, les boucles, etc.
Le principe est le suivant : depuis votre fichier JavaScript, vous appelez le template
de votre choix en lui transmettant les variables dont il a besoin pour construire la page
(voir figure 6.1).

Figure 6.1 Les templates avec Node.js

59

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS

Les bases dEJS


Comme il existe de nombreux systmes de templates, je vais en choisir un dans le lot.
Je vous propose ici dutiliser celui propos dans le code web suivant :


EJS
(Embedded
JavaScript)
B
Code web : 177569


Installez-le pour le projet :
npm install ejs

Nous pouvons maintenant dlguer la gestion de la vue (du HTML) notre moteur
de template. Plus besoin dcrire du HTML au milieu du code JavaScript comme
un cochon !
1
2
3

app . get ( '/ etage /: etagenum / chambre ' , function ( req , res ) {
res . render ( ' chambre . ejs ' , { etage : req . params . etagenum }) ;
}) ;

Ce code fait appel un fichier chambre.ejs qui doit se trouver dans un sousdossier appel views . Crez donc un fichier /views/chambre.ejs et placez-y le
code suivant :
1

<h1 > Vous tes dans la chambre </ h1 >

2
3

<p > Vous tes l ' tage n <%= etage % > </p >

La balise <%= etage %> sera remplace par la variable etage que lon a transmise au
template avec {etage: req.params.etagenum} !

Plusieurs paramtres et des boucles


Sachez que vous pouvez envoyer plusieurs paramtres vos templates, y compris
des tableaux ! Pour cette dmonstration, nous allons faire une application qui compte
jusqu un nombre envoy en paramtre et qui affiche un nom au hasard au sein dun
tableau (je suis en manque dinspiration, je le sais bien !).
Voici le code JavaScript :
1
2
3
4

app . get ( '/ compter /: nombre ' , function ( req , res ) {


var noms = [ ' Robert ' , ' Jacques ' , ' David ' ];
res . render ( ' page . ejs ' , { compteur : req . params . nombre , noms :
noms }) ;
}) ;

On transmet le nombre envoy en paramtre et une liste de noms sous forme de tableau.
Ensuite, dans le template EJS :
1
2

60

<h1 > Je vais compter jusqu ' <%= compteur % > </ h1 >

ALLER PLUS LOIN : CONNECT ET LES MIDDLEWARES


3
4
5

<p > <%


for ( var i = 1 ; i <= compteur ; i ++) {
%>

6
7

<%= i % >...

8
9

<% } % > </p >

10
11
12
13

<p > Tant que j 'y suis , je prends un nom au hasard qu ' on m 'a
envoy :
<%= noms [ Math . floor ( Math . random () * ( noms . length + 1 ) ) ] % >
</p >

Vous voyez quon peut faire des boucles avec les templates EJS. En fait, on utilise
la mme syntaxe que JavaScript (do la boucle for). Ma petite manipulation la fin
du code me permet de prendre un nom au hasard dans le tableau qui a t envoy au
template.
Et le rsultat la figure 6.2 (pour /compter/66).

Figure 6.2 Cette application est inutile, je sais :o)


De la mme faon, vous pouvez avoir recours des conditions (if) et des boucles
(while) au sein de vos templates EJS.
Nhsitez pas regarder aussi dautres systmes de templates comme sur les
sites jade-lang.com ou haml.info qui proposent une toute autre faon de crer
ses pages web !

Aller plus loin : Connect et les middlewares


Nous venons de voir deux fonctionnalits essentielles dExpress :
Les routes : elles permettent de grer efficacement les URLs.
Les vues : elles permettent un accs aux systmes de templates comme EJS.
Tout ceci est dj trs utile et lon pourrait tre tent de sarrter l, mais ce serait
passer ct du cur dExpress. Je vous propose daller plus loin en dcouvrant
ensemble comment fonctionnent les entrailles dExpress.
61

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS

Express, connect et les middlewares

Express est un framework construit au-dessus dun autre module appel Connect.
En fait, Express nest rien dautre que le module Connect auquel on a ajout
certaines fonctionnalits comme les routes et les vues.
Daccord, mais quest-ce que Connect dans ce cas ?

Cest un module qui permet dautres modules appels middlewares de communiquer entre eux, do son nom Connect . Il tend la fonctionnalit http.createServer()
fournie de base par Node.js et offre donc de nouvelles fonctionnalits.
Connect est fourni avec plus de dix-huitmiddlewares de base, et les dveloppeurs
peuvent bien entendu en proposer dautres via NPM. Les middlewares livrs avec
Connect fournissent chacun des micro-fonctionnalits. Il y a par exemple :
Compress : permet la compression gzip de la page pour un envoi plus rapide
au navigateur.
CookieParser : permet de manipuler les cookies.
Session : permet de grer des informations de session (durant la visite dun
visiteur).
Static : permet de renvoyer des fichiers statiques contenus dans un dossier
(images, fichiers tlcharger, etc.)
BasicAuth : permet de demander une authentification HTTP Basic, cest-dire une saisie dun login et dun mot de passe avant daccder une section
du site.
Csrf : fournit une protection contre les failles CSRF.
Etc.
Tous ces middlewares offrent vraiment des micro-fonctionnalits. Il y en a des tous
petits comme favicon par exemple, qui se contente de grer la favicon de votre
site (licne qui reprsente votre site).
Grce Connect, ces middlewares sont interconnects et peuvent communiquer
entre eux. Express ne fait quajouter les routes et les vues par-dessus lensemble (voir
schma la figure 6.3).
Le principe de Connect est que tous ces middlewares communiquent entre eux en
se renvoyant jusqu quatre paramtres :

err : les erreurs.


req : la requte du visiteur.
res : la rponse renvoyer (la page HTML et les informations den-tte).
next : un callback vers la prochaine fonction appeler.

Si je devais rsumer les potentialits de Connect dans un schma, cela donnerait la


figure 6.4.
62

ALLER PLUS LOIN : CONNECT ET LES MIDDLEWARES

Figure 6.3 Les fonctionnalits offertes par Express viennent en grande partie de
Connect

Figure 6.4 Les middlewares communiquent les paramtres grce Connect

63

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS


Nhsitez pas lire la doc. de Connect6 puis lire celle dExpress que vous
trouverez dans le code web suivant. Vous y trouverez toutes les informations
dont vous avez besoin pour utiliser les middlewares.

La doc. dExpress
B
Code web : 822156

Utiliser les fonctionnalits de Connect au sein dExpress


Si je vous raconte tout cela, cest parce que vous en avez besoin pour tirer pleinement
partie dExpress. En effet, vous pouvez appeler les diffrents modules de Connect
avec la mthode app.use(). Par exemple, vous pouvez faire :
1
2
3
4
5
6

app . use ( express . logger () ) // Active le middleware de logging


. use ( express . static ( __dirname + '/ public ') ) // Indique que le
dossier / public contient des fichiers statiques
. use ( express . favicon ( __dirname + '/ public / favicon . ico ') ) //
Active la favicon indiqu e
. use ( function ( req , res ) { // R pond enfin
res . send ( ' Hello ') ;
}) ;

Lordre dappel des middlewares est extrmement important. Par exemple,


on commence par activer le logger. Si on le faisait en dernier, on ne loggerait
rien ! Quand vous faites appel aux middlewares, rflchissez donc lordre,
car il peut impacter fortement le fonctionnement de votre application.
Comme vous le voyez, jai fait appel aux middlewares logger , static et
favicon dans le cas prsent. Chaque middleware va se renvoyer des donnes (la
requte, la rponse, la fonction suivante appeler, etc.). Chacun a un rle trs prcis.
Pour savoir les utiliser, il suffit de lire la documentation indique dans le code web
suivant :


La doc. de Connect
B
.
Code web : 235240


Je pourrais mtendre et prsenter les middlewares un un, mais ce serait long et
fastidieux (pour moi comme pour vous). Je ne souhaite pas rentrer plus dans le dtail,
mais jestime que vous savez lessentiel, ce qui tait le plus compliqu comprendre.
Je rsume : Express utilise Connect qui propose un ensemble de middlewares qui
communiquent entre eux. Appelez ces middlewares pour utiliser leurs fonctionnalits
et faites attention lordre dappel qui est important (on nactive pas un logger la
fin des oprations !).
Vous tes prts affronter le monde terrible et passionnant dExpress, un framework
incontournable qui volue rapidement. Bravo et bonne lecture de la documentation
maintenant !
64

ALLER PLUS LOIN : CONNECT ET LES MIDDLEWARES

En rsum
Express.js est un micro-framework pour Node.js. Les tches les plus courantes sont ainsi grandement facilites.
Express permet en particulier de grer plus simplement les routes (les diffrentes URL acceptes par votre application).
Express permet de faire le pont avec des moteurs de templates (comme
EJS). Ceux-ci nous permettent de sparer le code mtier (backend) du code
HTML (frontend). Finis les appels interminables la mthode write() !
Express est bas sur un autre module appel Connect. Celui-ci permet dappeler des mini-couches applicatives appeles middlewares qui offrent des
fonctionnalits comme les sessions, la compression gzip des pages, la manipulation des cookies, etc.

65

CHAPITRE 6. LE FRAMEWORK EXPRESS.JS

66

Chapitre

TP : la todo list
Difficult :
Je crois quil est grand temps de passer la pratique ! Nous avons fait le tour dun bon
nombre de fonctionnalits de base de Node.js et nous avons mme appris nous servir
du micro-framework Express. Pourtant, on a vraiment le sentiment davoir compris que
lorsque lon a pratiqu et ralis une premire vritable application. Cest ce que je vous
propose de faire dans ce TP.
Nous allons raliser ici une to do list (une liste de tches). Le visiteur pourra simplement
ajouter et supprimer des tches. Nous ferons donc quelque chose de trs simple pour
commencer. Vous pourrez ensuite lamliorer comme bon vous semble !

67

CHAPITRE 7. TP : LA TODO LIST

Besoin daide ?
Avant toute chose, je vais vous prsenter la page que nous devons crer ; il sagit de la
figure 7.1.

Figure 7.1 Lapplication que nous allons crer


On peut ajouter des lments la to do list via le formulaire.
On peut supprimer des lments en cliquant sur les croix dans la liste.
La liste est stocke dans la session du visiteur. Si quelquun dautre se connecte,
il aura sa propre liste.
Les instructions sont simples et le code final ne sera pas trs long. En revanche, si cest
votre premire application un peu complte avec Node.js vous allez srement ttonner
et avancer doucement. Ne prenez pas peur, cest parfaitement normal ! Persvrez et, si
vraiment vous avez besoin daide, lisez la section Un peu daide avant de comparer
votre travail avec le mien.
Noubliez pas douvrir les documents dExpress6 et de Connect6 propos dans
les code web correspondants. Je naurais jamais pu faire ce TP moi-mme
sans avoir recours la documentation !
Vous avez toutes les infos, vous de jouer !

Les modules et le package.json


Respirons un grand coup et prenons les choses dans lordre. De quoi a-t-on besoin ?
Express : sans le framework Express la mission sera vraiment trs difficile.
Maintenant que nous savons utiliser ce framework, ce serait dommage de sen
priver.
EJS (ou un autre systme de template) : cela nous permettra de construire
facilement la page HTML qui affiche la liste des tches et le formulaire.
A priori ,ces modules suffisent. Une premire bonne pratique serait de se crer un
fichier package.json dans le dossier de notre projet :
1
2

68

" name " : " ma - todolist " ,

BESOIN DAIDE ?
3
4
5
6
7
8
9
10

" version " : " 0 . 1 . 0 " ,


" dependencies " : {
" express " : " ~ 3 . 2 . 1 " ,
" ejs " : " ~ 0 . 8 . 3 "
},
" author " : " Mateo21 < mateo21@email . com > " ,
" description " : " Un gestionnaire de todolist ultra basique "

Vous pouvez videmment remplacer le nom, lauteur et la description comme bon vous
semble.
Pour les numros de version dExpress et dEJS, je me suis bas sur les versions
disponibles au moment de la rdaction de ce cours. Comme lunivers de Node.js avance
vite, vous aurez srement des versions plus rcentes. Le tilde ( ~ ) permet dautoriser
les futurs patchs de ces modules, mais pas les nouvelles versions mineures ou majeures,
ce qui nous garantit que leur API ne changera pas, et donc que notre code continuera
fonctionner mme avec ces mises jour.
Maintenant que vous avez votre package.json, installez les dpendances avec un
simple :
npm install

Nous sommes prts travailler !

Les routes
Je vous avais dit que bien dfinir ses routes tait important lorsque lon construit une
application web. Si vous hsitez et ne savez pas par o commencer, je vous invite
lister les routes de votre application. Que doit-elle faire ?
Lister les tches.
Ajouter une tche.
Supprimer une tche.
A priori, on peut associer une route chacune de ces fonctionnalits :
/todo : liste les tches.
/todo/ajouter : ajoute une tche.
/todo/supprimer/:id : supprime la tche nid.
Vous allez donc crire les routes comme ceci dans votre fichier app.js :
1

. get ( '/ todo ' , function ( req , res ) {

2
3

}) ;

4
5

// ...

En revanche, il faudrait que nous nous penchions un instant sur la question du formulaire. En gnral, les formulaires envoient les donnes avec la mthode POST et
69

CHAPITRE 7. TP : LA TODO LIST


non la mthode GET. Lajout dune tche va donc se faire sur la route /todo/ajouter,
mais avec la mthode POST. Cest pour cela quau lieu de faire appel .get(), nous
devrions faire appel .post() pour cette route :
1

. post ( '/ todo / ajouter / ' , function ( req , res ) {

2
3

})

Bien chaner les appels aux middlewares


Nous savons que nous aurons besoin dun systme de sessions. La documentation
de Connect nous indique comment utiliser les sessions dans le code web suivant. On
apprend que les sessions utilisent les cookies et quil faut donc activer les cookies
avant dactiver les sessions. Voil encore un exemple de limportance de lordre dappel
des middlewares !


Comment utiliser les sessions
B
Code web : 527765


Autre chose : nous aurons besoin de rcuprer les donnes du formulaire dans /todo/ajouter.
Nous avons appris rcuprer des paramtres depuis lURL mais pas depuis les formulaires. En fait, cest vraiment simple : il vous suffit dinclure le middleware que
vous trouverez sur le site propos dans le code web suivant. Vous aurez ensuite accs
req.body.nomDuChamp.


BodyParser
B
Code web : 267545


Du coup, le dbut de notre code JavaScript devrait ressembler quelque chose comme
a :
1

var express = require ( ' express ') ;

2
3

var app = express () ;

4
5
6
7
8

/* On utilise les cookies , les sessions et les formulaires */


app . use ( express . cookieParser () )
. use ( express . session ({ secret : ' todotopsecret ' }) )
. use ( express . bodyParser () )

9
10
11

/* Gestion des routes en - dessous


....
*/

Le paramtre secret envoy au module de session est obligatoire : il permet de


scuriser les cookies de session. Envoyez la valeur de votre choix. Notez que vous
pouvez envoyer dautres options, comme la dure de vie du cookie de session (par
dfaut, la session durera tant que le navigateur restera ouvert). Consultez la liste dans
ce code web7.
Allez, je vous en ai trop dit dj, vous de coder !
70

CORRECTION

Correction
Allez, cest lheure de la correction ! Ne lisez cette section que si vous avez russi ou
que toutes vos tentatives ont chou et que vous tes dsesprs.
Le code nest pas si difficile lire au final. Il nest pas trs long non plus, mais il fallait
bien rflchir pour trouver quoi crire exactement.

La solution
Voici le code JavaScript que jai produit dans le fichier principal app.js. Notez bien
que cest une faon de faire et que vous ntes pas obligs davoir produit un code
strictement identique au mien !
1

var express = require ( ' express ') ;

2
3

var app = express () ;

4
5
6
7
8

/* On utilise les cookies , les sessions et les formulaires */


app . use ( express . cookieParser () )
. use ( express . session ({ secret : ' todotopsecret ' }) )
. use ( express . bodyParser () )

9
10
11
12
13
14
15
16
17

/* S ' il n ' y a pas de todolist dans la session ,


on en cr e une vide sous forme d ' array avant la suite */
. use ( function ( req , res , next ) {
if ( typeof ( req . session . todolist ) == ' undefined ') {
req . session . todolist = [];
}
next () ;
})

18
19
20
21
22

/* On affiche la todolist et le formulaire */


. get ( '/ todo ' , function ( req , res ) {
res . render ( ' todo . ejs ' , { todolist : req . session . todolist }) ;
})

23
24
25
26
27
28
29
30

/* On ajoute un l ment la todolist */


. post ( '/ todo / ajouter / ' , function ( req , res ) {
if ( req . body . newtodo != ' ') {
req . session . todolist . push ( req . body . newtodo ) ;
}
res . redirect ( '/ todo ') ;
})

31
32
33
34
35
36

/* Supprime un l ment de la todolist */


. get ( '/ todo / supprimer /: id ' , function ( req , res ) {
if ( req . params . id != ' ') {
req . session . todolist . splice ( req . params . id , 1 ) ;
}

71

CHAPITRE 7. TP : LA TODO LIST


37
38

})

res . redirect ( '/ todo ') ;

39
40
41
42
43

/* On redirige vers la todolist si la page demand e n ' est pas


trouv e */
. use ( function ( req , res , next ) {
res . redirect ( '/ todo ') ;
})

44
45

. listen ( 8080 ) ;

Beau chanage de middlewares nest-ce pas ? :-


Il y a aussi un fichier de template qui va avec. Le fichier todo.ejs :
1

<! DOCTYPE html >

2
3
4
5
6
7
8
9

< html >


< head >
< title > Ma todolist </ title >
< style >
a { text - decoration : none ; color : black ;}
</ style >
</ head >

10

< body >


<h1 > Ma todolist </ h1 >

11
12
13

<ul >
<\% todolist . forEach ( function ( todo , index ) { \% >
<li > < a href = " / todo / supprimer / <\%= index \% > " >X </ a >
<\%= todo \% > </ li >
<\% }) ; \% >
</ ul >

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

< form action = " / todo / ajouter / " method = " post " >
<p >
< label for = " newtodo " > Que dois - je faire ? </ label
>
< input type = " text " name = " newtodo " id = " newtodo "
autofocus / >
< input type = " submit " / >
</p >
</ form >
</ body >
</ html >

Et avec a, lindispensable package.json qui permet dinstaller les dpendances avec


un simple npm install :
1
2

72

" name " : " ma - todolist " ,

CORRECTION
3
4
5
6
7
8
9
10

" version " : " 0 . 1 . 0 " ,


" dependencies " : {
" express " : " ~ 3 . 2 . 1 " ,
" ejs " : " ~ 0 . 8 . 3 "
},
" author " : " Mateo21 < mateo21@email . com > " ,
" description " : " Un gestionnaire de todolist ultra basique "

Les explications
Mon code est dj assez comment, cela devrait vous permettre de vous y retrouver.
Vous remarquerez que je me suis permis de rediriger le visiteur vers la liste (/todo)
aprs un ajout ou une suppression dlment, avec res.redirect(/todo).
La liste des tches est stocke dans un array (tableau). Cest dailleurs lui qui est la
cause de la petite subtilit de ce programme : comme JavaScript napprcie pas que
lon essaie de parcourir des arrays qui nexistent pas, jai cr un middleware qui
cre un array vide si le visiteur na pas de to do list (parce quil vient de commencer
sa session par exemple). Cest le rle de ce code :
1
2
3
4
5
6

. use ( function ( req , res , next ) {


if ( typeof ( req . session . todolist ) == ' undefined ') {
req . session . todolist = [];
}
next () ;
})

Cette fonction middleware reoit la requte, la rponse et la prochaine fonction


excuter. Jai donc crit moi-mme un middleware linstar de cookieParser(),
session() et bodyParser(). Son rle est trs simple : il vrifie sil y a une to do list
dans la session et, si ce nest pas le cas, il cre un array vide (do les []). Cela nous
vite beaucoup derreurs par la suite.
Pourquoi avoir cr un middleware ? Parce que cest le seul moyen ma disposition
pour excuter des fonctionnalits avant le chargement de nimporte quelle page. Pour
que le middleware passe le bb son voisin , je dois finir imprativement par
un appel next() (la fonction suivante). Dans le cas prsent, next() fait rfrence
.get(/todo, function() {}).
part a, rien de vraiment particulier. Jajoute des lments la fin du tableau avec
.push() et je retire des lments avec .splice(), mais a cest du JavaScript de
base.
Du ct du template, quest-ce quil y a de particulier ? Pas grand chose, si ce nest
que je parcours la to do list avec un forEach (l encore, cest du JavaScript) :
1
2

<\% todolist . forEach ( function ( todo , index ) { \% >


<li > < a href = " / todo / supprimer / <\%= index \% > " >X </ a > <\%=
todo \% > </ li >

73

CHAPITRE 7. TP : LA TODO LIST


3

<\% }) ; \% >

La croix pour supprimer un lment est un simple caractre Unicode (vive


Unicode). Vous nimaginez pas le nombre de symboles Unicode quon peut
trouver en faisant une recherche Google du type unicode cross , unicode
smiley , unicode plane , unicode arrow , etc.

Tlcharger le projet
Je vous ai donn tout le code du projet, mais si vous insistez pour tlcharger le tout
dans un fichier .zip, aller sur le code web suivant. Noubliez pas de faire un npm install
pour installer les dpendances avant de lexcuter !


Fichier .zip
B
Code web : 543618

Allez plus loin !


Ma petite to do list est trs basique. Vous pouvez lui ajouter de nombreuses fonctionnalits :

Modification des noms des tches.


Ragencement des tches entre elles.
Exportation CSV.
Attribution dune priorit et dune date limite.
Persistance de la to do list (stockage dans une base de donnes ou une base
NoSQL).
Partage dune to do list entre plusieurs personnes.
Synchronisation de la to do list en temps rel entre les personnes sans avoir
besoin de recharger la page.
Certaines de ces fonctionnalits sont plus faciles raliser que dautres. Si vous souhaitez en crer de nouvelles, il vous faudra dcouvrir et utiliser de nouveaux modules.
Vous avez de quoi vous amuser pendant un bon petit moment, bon courage !

74

Troisime partie

La communication temps rel


avec socket.io

75

Chapitre

socket.io : passez au temps rel !


Difficult :
Socket.io est lune des bibliothques les plus prises par ceux qui dveloppent avec Node.js.
Pourquoi ? Parce quelle permet de faire trs simplement de la communication synchrone
dans votre application, cest--dire de la communication en temps rel ! Vous ne voyez pas
ce que a signifie ? Laissez-moi vous le dire autrement : socket.io vous permet par exemple
de mettre en place trs facilement un Chat sur votre site !
Les possibilits que vous offre socket.io sont en ralit immenses et vont bien au-del du
Chat : tout ce qui ncessite une communication immdiate entre les visiteurs de votre site
peut en bnficier. Cela peut tre par exemple une brique de base pour mettre en place
un jeu o on voit en direct les personnages voluer dans le navigateur, le tout sans avoir
recharger la page !
Cela donne envie, non !

77

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !

Que fait socket.io ?


Avant de commencer coder, je voudrais vous prsenter rapidement le principe de socket.io. Cest une bibliothque qui nous simplifie beaucoup les choses, mais on pourrait
croire tort que cest de la magie . Or, socket.io se base sur plusieurs techniques diffrentes qui permettent la communication en temps rel (et qui pour certaines existent
depuis des annes !). La plus connue dentre elles, et la plus rcente, est WebSocket.

WebSocket ? Ce nest pas une des nouveauts de HTML5 ?

Cest une nouveaut rcente apparue plus ou moins en mme temps que HTML5, mais
ce nest pas du HTML : cest une API JavaScript. WebSocket est une fonctionnalit
supporte par lensemble des navigateurs rcents. Elle permet un change bilatral
synchrone entre le client et le serveur.
Comment a je parle chinois ? ! Reprenons les bases. Habituellement, sur le web, la
communication est asynchrone. Le web a toujours t conu comme cela : le client
demande et le serveur rpond (voir figure 8.1).

Figure 8.1 Habituellement, la communication est asynchrone : le client demande, le


serveur rpond
Ctait suffisant aux dbuts du web, mais cela est devenu trop limitant ces derniers
temps. Nous avons besoin dune communication plus ractive et immdiate. Dans ce
schma par exemple, le serveur ne peut pas dcider de lui-mme denvoyer quelque
chose au client (par exemple pour lavertir : eh il y a un nouveau message ! ). Il faut
que le client recharge la page ou fasse une action pour solliciter le serveur car celui-ci
na pas le droit de sadresser au client tout seul.
WebSocket est une nouveaut du web qui permet de laisser une sorte de tuyau de
communication ouvert entre le client et le serveur. Le navigateur et le serveur restent
connects entre eux et peuvent schanger des messages, dans un sens comme dans
lautre, dans ce tuyau. Dsormais, le serveur peut donc lui-mme dcider denvoyer un
message au client comme un grand (voir figure 8.2) !
78

QUE FAIT SOCKET.IO ?

Figure 8.2 Avec les WebSocket, la communication est synchrone : un tuyau de


communication reste ouvert entre client et serveur

Ne confondez pas WebSocket et AJAX ! AJAX permet effectivement au


client et au serveur dchanger des informations sans recharger la page. Mais
en AJAX, cest toujours le client qui demande et le serveur qui rpond. Le
serveur ne peut pas dcider de lui-mme denvoyer des informations au client.
Avec WebSocket, cela devient possible !
Socket.io nous permet dutiliser les WebSockets trs facilement. Et, comme tous les
navigateurs ne grent pas WebSocket, il est capable dutiliser dautres techniques de
communication synchrones si elles sont gres par le navigateur du client. Par exemple,
rendez-vous sur le lien du site indiqu dans le code web suivant :


Browser support de SoB cket.io/
Code web : 602570


On voit que socket.io dtermine pour chaque client quelle est la mthode de communication temps rel la plus adapte pour le client :

WebSocket.
Adobe Flash Socket.
AJAX long polling.
AJAX multipart streaming.
Forever Iframe.
JSONP Polling.
79

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


Par exemple, si le navigateur ne supporte pas WebSocket mais que Flash est
install, socket.io passera par Flash pour faire de la communication temps
rel. Sinon, il peut utiliser dautres techniques comme lAJAX Long Polling
(le client demande en continu au serveur sil a des nouveauts pour lui (pas
le plus propre ni le plus efficace mais a marche) ou encore la Forever
Iframe qui se base sur une iframe invisible qui se charge progressivement
pour rcuprer les nouveauts du serveur. La bonne nouvelle, cest que vous
navez pas besoin de connatre le dtail du fonctionnement de ces techniques.
Par contre, je pense que cest bien au moins de connatre leur nom et de
savoir quelles existent.
Grce toutes ces diffrentes techniques de communication, socket.io supporte un
trs grand nombre de navigateurs, mme anciens :

Internet Explorer 5.5+ (oui oui, vous avez bien lu !).


Safari 3+.
Google Chrome 4+.
Firefox 3+.
Opera 10.61+.
Safari sur iPhone et iPad.
Le navigateur Android.

Maintenant que nous en savons un petit peu plus sur le fonctionnement de socket.io,
si nous commencions lutiliser ?

mettre et recevoir des messages avec socket.io


Parlons peu, mais parlons bien. Comment utiliser socket.io ?

Installer socket.io
La premire tape, aussi vidente soit-elle, est dinstaller socket.io. Ne riez pas, la
premire fois que jai voulu lutiliser jai bien perdu quinze minutes avant de comprendre
que javais oubli de faire un simple :
npm install socket . io

Je vous ai fait doncgagner 15 minutes de votre vie ! Ne me remerciez pas cest tout
naturel.

Premier code : un client se connecte


Lorsque lon utilise socket.io, on doit toujours soccuper de deux fichiers en mme
temps :
80

METTRE ET RECEVOIR DES MESSAGES AVEC SOCKET.IO


Le fichier serveur (ex : app.js) : cest lui qui centralise et gre les connexions
des diffrents clients connects au site.
Le fichier client (ex : index.html) : cest lui qui se connecte au serveur et qui
affiche les rsultats dans le navigateur.
Le serveur (app.js)
Jai volontairement spar le code du serveur en deux parties : au dbut, on charge le
serveur comme dhabitude (et on rcupre et renvoie le contenu de la page index.html) ;
ensuite, on charge socket.io et on gre les vnements de socket.io.
1
2

var http = require ( ' http ') ;


var fs = require ( ' fs ') ;

3
4
5
6
7
8
9
10

// Chargement du fichier index . html affich au client


var server = http . createServer ( function ( req , res ) {
fs . readFile ( ' ./ index . html ' , 'utf - 8 ' , function ( error ,
content ) {
res . writeHead ( 200 , { " Content - Type " : " text / html " }) ;
res . end ( content ) ;
}) ;
}) ;

11
12
13

// Chargement de socket . io
var io = require ( ' socket . io ') . listen ( server ) ;

14
15
16
17
18

// Quand on client se connecte , on le note dans la console


io . sockets . on ( ' connection ' , function ( socket ) {
console . log ( ' Un client est connect ! ') ;
}) ;

19
20

server . listen ( 8080 ) ;

Ce code fait deux choses :


Il renvoie le fichier index.html quand un client demande charger la page dans
son navigateur.
Il se prpare recevoir des requtes via socket.io. Ici, on sattend recevoir
un seul type de message : la connexion. Lorsquon se connecte via socket.io,
on logge ici linformation dans la console.
Imaginez-vous en tant que visiteur. Vous ouvrez votre navigateur ladresse o se
trouve votre application (http://localhost:8080 ici). On vous envoie le fichier index.html,
la page se charge. Dans ce fichier, que nous allons voir juste aprs, un code JavaScript se connecte au serveur, cette fois pas en http mais via socket.io (donc via les
WebSockets en gnral). Le client effectue donc deux types de connexion :
Une connexion classique au serveur en HTTP pour charger la page index.html.
Une connexion temps rel pour ouvrir un tunnel via les WebSockets grce
socket.io.
81

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


Le client (index.html)
Intressons-nous maintenant au client. Le fichier index.html est envoy par le serveur
Node.js. Cest un fichier HTML tout ce quil y a de plus classique, si ce nest quil
contient un peu de code JavaScript qui permettra ensuite de communiquer avec le
serveur en temps rel via socket.io :
1
2
3
4
5
6

<! DOCTYPE html >


< html >
< head >
< meta charset = " utf - 8 " / >
< title > Socket . io </ title >
</ head >

7
8
9

< body >


<h1 > Communication avec socket . io ! </ h1 >

10
11
12
13
14
15
16

< script src = " / socket . io / socket . io . js " > </ script >
< script >
var socket = io . connect ( ' http :// localhost : 8080 ') ;
</ script >
</ body >
</ html >

Jai plac le code JavaScript la fin du code HTML volontairement. Bien


sr, on pourrait le mettre dans la balise <head> comme beaucoup le font,
mais le placer la fin du code HTML permet dviter que le chargement du
JavaScript ne bloque le chargement de la page HTML. Au final, cela donne
limpression dune page web qui se charge plus rapidement.
Dans un premier temps, on fait rcuprer au client le fichier socket.io.js. Celui-ci est
automatiquement fourni par le serveur Node.js via le module socket.io (le chemin
vers le fichier nest donc pas choisi au hasard) :
1

< script src = " / socket . io / socket . io . js " > </ script >

Le code quil contient permet de grer la communication avec le serveur du ct du


client, soit avec les WebSockets, soit avec lune des autres mthodes dont je vous ai
parl si le navigateur ne les supporte pas.
Ensuite, nous pouvons effectuer des actions du ct du client pour communiquer
avec le serveur. Pour le moment, jai fait quelque chose de trs simple : je me suis
content de me connecter au serveur. Celui-ci se trouve sur ma machine, do ladresse
http://localhost:8080. videmment, sur le web, il faudra adapter ce chemin pour
indiquer ladresse de votre site (ex : http://monsite.com).
1

82

var socket = io . connect ( ' http :// localhost : 8080 ') ;

METTRE ET RECEVOIR DES MESSAGES AVEC SOCKET.IO


Testons le code !
Il nous suffit de lancer lapplication :
node app . js

On peut alors se rendre avec notre navigateur cette adresse Node.js :


http://localhost:8080.
Une page basique va se charger. Votre ordinateur va ensuite ouvrir une connexion avec
socket.io et le serveur devrait afficher des informations de dbogage dans la console :
$ node app . js
info - socket . io started
debug - client authorized
info - handshake authorized Z2E7aqIvOPPqv_XBn421
debug - setting request GET / socket . io /1/ websocket /
Z 2 E 7 a q I vOPPqv_XBn421
debug - set heartbeat interval for client
Z 2 E 7 a q I vOPPqv_XBn421
debug - client authorized for
debug - websocket writing 1::
Un client est connect !

Super ! Cela veut dire que notre code fonctionne.


Pour le moment il ne fait rien de bien extraordinaire, mais nous avons les bases. a va
tre le moment de samuser changer des messages avec le serveur !

Envoi et rception de messages


Maintenant que le client est connect, on peut changer des messages entre le client et
le serveur. Il y a deux cas de figure :
Le serveur veut envoyer un message au client.
Le client veut envoyer un message au serveur.
Le serveur veut envoyer un message au client
Je propose que le serveur envoie un message au client lorsquil vient de se connecter,
pour lui confirmer que la connexion a bien fonctionn. Rajoutez ceci au fichier app.js :
1
2
3

io . sockets . on ( ' connection ' , function ( socket ) {


socket . emit ( ' message ' , ' Vous tes bien connect ! ') ;
}) ;

Lorsque lon dtecte une connexion, on met un message au client avec socket.emit().
La fonction prend deux paramtres :
83

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


Le type de message quon veut transmettre. Ici, mon message est de type message
(je ne suis pas trs original, je sais). Cela vous permettra de distinguer les diffrents types de message. Par exemple, dans un jeu, on pourrait envoyer des
messages de type deplacement_joueur, attaque_joueur.
Le contenu du message. L vous pouvez transmettre ce que vous voulez.
Si vous voulez envoyer plusieurs donnes diffrentes avec votre message, regroupez-les
sous forme dobjet comme ceci par exemple :
1

socket . emit ( ' message ' , { content : ' Vous tes bien connect ! ' ,
importance : '1 ' }) ;

Du ct du fichier index.html (le client), on va couter larrive de messages de type


message :
1
2
3
4
5
6

< script >


var socket = io . connect ( ' http :// localhost : 8080 ') ;
socket . on ( ' message ' , function ( message ) {
alert ( ' Le serveur a un message pour vous : ' + message )
;
})
</ script >

Avec socket.on(), on coute les messages de type message. Lorsque des messages
arrivent, on appelle la fonction de callback qui, ici, affiche simplement une bote de
dialogue.
Essayez, vous verrez que lorsque vous chargez la page index.html, une bote de dialogue
saffiche indiquant que la connexion a russi (voir figure 8.3) !

Figure 8.3 Le client affiche le message du serveur dans une bote de dialogue
Le client veut envoyer un message au serveur
Maintenant, faisons linverse. Je vous propose dajouter un bouton dans la page web
et denvoyer un message au serveur lorsquon clique dessus.

Du ct du client (index.html), je vais rajouter un bouton Embter le serveur .
Lorsquon cliquera dessus, jmettrai un message au serveur. Voici le code complet :
84

METTRE ET RECEVOIR DES MESSAGES AVEC SOCKET.IO


1
2
3
4
5
6

<! DOCTYPE html >


< html >
< head >
< meta charset = " utf - 8 " / >
< title > Socket . io </ title >
</ head >

7
8
9

< body >


<h1 > Communication avec socket . io ! </ h1 >

10
11

<p > < input type = " button " value = " Emb ter le serveur " id = "
poke " / > </p >

12
13
14
15
16
17
18
19

< script src = " http :// code . jquery . com / jquery - 1 . 10 . 1 . min .
js " > </ script >
< script src = " / socket . io / socket . io . js " > </ script >
< script >
var socket = io . connect ( ' http :// localhost : 8080 ') ;
socket . on ( ' message ' , function ( message ) {
alert ( ' Le serveur a un message pour vous : ' +
message ) ;
})

20
21
22
23
24
25
26

$ ( '# poke ') . click ( function () {


socket . emit ( ' message ' , ' Salut serveur , a va ? '
);
})
</ script >
</ body >
</ html >

Jutilise ici jQuery pour des raisons pratiques (parce que jai lhabitude) pour
rcuprer lvnement du clic sur le bouton, mais ce nest absolument pas
obligatoire. On peut faire a en pur JavaScript si on veut.
Finalement, le seul code nouveau et intressant ici est :
1
2
3

$ ( '# poke ') . click ( function () {


socket . emit ( ' message ' , ' Salut serveur , a va ? ') ;
})

Il est trs simple. Lorsque lon clique sur le bouton, on envoie un message de type
message au serveur, assorti dun contenu.
Si on veut rcuprer cela du ct du serveur maintenant, il va nous falloir ajouter
lcoute des messages de type message dans la fonction de callback de la connexion :
1
2

io . sockets . on ( ' connection ' , function ( socket ) {


socket . emit ( ' message ' , ' Vous tes bien connect ! ') ;

85

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


4
5
6
7

}) ;

// Quand le serveur re oit un signal de type " message " du


client
socket . on ( ' message ' , function ( message ) {
console . log ( ' Un client me parle ! Il me dit : ' +
message ) ;
}) ;


Lancez le code ! Cliquez sur le bouton Embter le serveur dans la page et regardez
dans la console du serveur. Vous devriez voir apparatre la figure 8.4.
Un client me parle ! Il me dit : Salut serveur , a va ?

Figure 8.4 Lorsque le client clique sur le bouton, le serveur ragit immdiatement
dans la console

86

COMMUNIQUER AVEC PLUSIEURS CLIENTS

Communiquer avec plusieurs clients


Dans tous nos exemples prcdents, on a travaill avec un serveur et un seul client. Dans
la pratique, vous aurez srement plusieurs clients connects votre application Node.js
(en tout cas je vous le souhaite !). Pour simuler cela en local, cest trs simple : il suffit
douvrir deux onglets, chacun sur votre page http://localhost:8080. Le serveur verra
deux clients diffrents connects.
Lorsque lon a plusieurs clients, il faut tre capable :
Denvoyer des messages tout le monde dun seul coup. On appelle a les broadcasts.
De se souvenir dinformations sur chaque client (comme son pseudo par exemple).
On a besoin pour a de variables de session.
surprise, cest justement ce que je comptais vous expliquer maintenant !

Envoyer un message tous les clients (broadcast)


Quand vous faites un socket.emit() du ct du serveur, vous envoyez uniquement un
message au client avec lequel vous tes en train de discuter. Mais vous pouvez faire
plus fort : vous pouvez envoyer un broadcast, cest--dire un message destin tous
les autres clients (except celui qui vient de solliciter le serveur).
Prenons un cas :
1. Le client A envoie un message au serveur.
2. Le serveur lanalyse.
3. Il dcide de broadcaster ce message pour lenvoyer aux autres clients connects :
B et C.
La figure 8.5 montre cela.
Imaginez par exemple un Chat. Le client A crit un message et lenvoie au serveur.
Pour que les autres clients voient ce message, il doit le leur broadcaster. Pour cela, rien
de plus simple !
1

socket . broadcast . emit ( ' message ' , ' Message toutes les unit s .
Je r p te , message toutes les unit s . ') ;

Il suffit de faire un socket.broadcast.emit() et le message partira vers tous les autres


clients connects. Ajoutez par exemple un broadcast dans app.js lors de la connexion
dun client :
1
2
3

io . sockets . on ( ' connection ' , function ( socket ) {


socket . emit ( ' message ' , ' Vous tes bien connect ! ') ;
socket . broadcast . emit ( ' message ' , ' Un autre client vient
de se connecter ! ') ;

4
5

socket . on ( ' message ' , function ( message ) {

87

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !

Figure 8.5 Dans un broadcast, le serveur envoie un message tous les autres clients
connects

6
7
8

}) ;

}) ;

console . log ( ' Un client me parle ! Il me dit : '


+ message ) ;

Essayez maintenant douvrir deux onglets (ou plus) sur votre page http://localhost:8080.
Vous verrez que lorsquun nouveau client arrive, les autres pages ragissent instantanment pour dire : Un autre client vient de se connecter !

Les variables de session


Lorsque vous aurez plusieurs clients connects, vous allez vite vous rendre compte quil
est dlicat de les reconnatre. Lidal serait de pouvoir mmoriser des informations sur
chaque client. Et a tombe bien, cest justement a que servent les variables de
session !
Le serveur peut retenir des informations sur chaque client connect. Comme a, le client
naura pas besoin de rappeler qui il est chaque fois quil envoie un message !
Pour stocker une variable de session ct serveur, il suffit dcrire :
1

88

socket . set ( ' nomVariable ' , data ) ;

COMMUNIQUER AVEC PLUSIEURS CLIENTS


Dans cet exemple, on stocke les donnes (contenues dans la variable data) dans une
variable de session nomme nomVariable.
Pour rcuprer cette information ensuite, il faudra faire appel get(). Comme avec
Node.js on adore les fonctions de callback (pour ne pas bloquer le serveur pendant
quil rcupre linformation), il va falloir donner une fonction de callback qui sera
excute ds que le serveur aura la variable en main :
1
2
3

socket . get ( ' nomVariable ' , function ( error , data ) {


console . log ( data ) ;
}) ;

Ici, on demande rcuprer la variable de session nomVariable. Ds que le serveur


la obtenu, il excute la fonction situe lintrieur. Cette dernire peut alors faire ce
quelle veut avec les donnes.
Simple non ? Essayons dimaginer un cas pratique. Lorsquun client se connecte, la page
web va lui demander son pseudo. Le serveur stockera
le pseudo en variable de session

pour sen souvenir lorsque le client cliquera sur Embter le serveur .
Voyons les modifications que nous devons faire. . .
La page web (index.html) met un signal contenant le pseudo
Au chargement de la page web, nous allons demander le pseudo du visiteur. On envoie
ce pseudo au serveur via un signal de type petit_nouveau (je lai appel comme a
pour le diffrencier des signaux de type message). Ce signal contient le pseudo du
visiteur :
1
2

var pseudo = prompt ( ' Quel est votre pseudo ? ') ;


socket . emit ( ' petit_nouveau ' , pseudo ) ;

Le serveur (app.js) stocke le pseudo


Le serveur doit rcuprer ce signal. Nous coutons alors les signaux de type petit_nouveau
et, lorsque lon en reoit, on sauvegarde le pseudo en variable de session :
1
2
3

socket . on ( ' petit_nouveau ' , function ( pseudo ) {


socket . set ( ' pseudo ' , pseudo ) ;
}) ;

Le serveur (app.js) se rappelle du pseudo quand on lui envoie un message


Maintenant, nous voulons que le serveur se souvienne de nous lorsque nous lembtons
en cliquant sur Embter le serveur  (ce qui provoque lenvoi dun signal de type
message). On va complter la fonction de callback qui est appele quand le serveur
reoit un message :
89

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


1
2
3
4
5

socket . on ( ' message ' , function ( message ) {


socket . get ( ' pseudo ' , function ( error , pseudo ) {
console . log ( pseudo + ' me parle ! Il me dit : ' +
message ) ;
}) ;
}) ;

Ds que lon reoit un message, on demande rcuprer la variable de session pseudo.


Ds que lon a rcupr la variable de session pseudo, on peut logger linformation dans
la console pour se souvenir du nom de la personne qui vient denvoyer le message.
Javoue que ces fonctions de callback imbriques peuvent un peu donner le tournis,
mais vous avez voulu faire du Node.js, il faut assumer maintenant.

Tester le code
Essayez douvrir
deux fentres en donnant un pseudo diffrent chaque fois. Cliquez

ensuite sur Embter le serveur . Vous verrez dans la console que le pseudo de la
personne qui a cliqu sur le bouton apparat !
Jai fait un essai chez moi avec deux fentres, lune avec le pseudo mateo21 et lautre
avec le pseudo robert . la figure 8.6, vous voyez en bas de la console que celle-ci
reconnat bien qui vient de cliquer !

Figure 8.6 Plusieurs clients connects : le serveur se souvient de leurs noms !

90

COMMUNIQUER AVEC PLUSIEURS CLIENTS


Le code complet
Je vous ai volontairement montr des morceaux de code trs courts pour vous expliquer
le principe, mais je suis sr que vous mourez denvie davoir le code complet pour faire
vos essais.
Alors allons-y ! Voici index.html :
1
2
3
4
5
6

<! DOCTYPE html >


< html >
< head >
< meta charset = " utf - 8 " / >
< title > Socket . io </ title >
</ head >

7
8
9

< body >


<h1 > Communication avec socket . io ! </ h1 >

10
11

<p > < input type = " button " value = " Emb ter le serveur " id = "
poke " / > </p >

12
13
14
15
16

< script src = " http :// code . jquery . com / jquery - 1 . 10 . 1 . min .
js " > </ script >
< script src = " / socket . io / socket . io . js " > </ script >
< script >
var socket = io . connect ( ' http :// localhost : 8080 ') ;

17
18
19
20
21

// On demande le pseudo au visiteur ...


var pseudo = prompt ( ' Quel est votre pseudo ? ') ;
// Et on l ' envoie avec le signal " petit_nouveau " (
pour le diff rencier de " message ")
socket . emit ( ' petit_nouveau ' , pseudo ) ;

22
23
24
25
26

// On affiche une bo te de dialogue quand le


serveur nous envoie un " message "
socket . on ( ' message ' , function ( message ) {
alert ( ' Le serveur a un message pour vous : ' +
message ) ;
})

27
28
29
30
31
32
33
34

// Lorsqu ' on clique sur le bouton , on envoie un "


message " au serveur
$ ( '# poke ') . click ( function () {
socket . emit ( ' message ' , ' Salut serveur , a va ? '
);
})
</ script >
</ body >
</ html >

. . . et voici lapplication serveur app.js :


91

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !


1
2

var http = require ( ' http ') ;


var fs = require ( ' fs ') ;

3
4
5
6
7
8
9
10

// Chargement du fichier index . html affich au client


var server = http . createServer ( function ( req , res ) {
fs . readFile ( ' ./ index . html ' , 'utf - 8 ' , function ( error ,
content ) {
res . writeHead ( 200 , { " Content - Type " : " text / html " }) ;
res . end ( content ) ;
}) ;
}) ;

11
12
13

// Chargement de socket . io
var io = require ( ' socket . io ') . listen ( server ) ;

14
15
16
17
18
19

io . sockets . on ( ' connection ' , function ( socket , pseudo ) {


// Quand on client se connecte , on lui envoie un message
socket . emit ( ' message ' , ' Vous tes bien connect ! ') ;
// On signale aux autres clients qu ' il y a un nouveau venu
socket . broadcast . emit ( ' message ' , ' Un autre client vient de
se connecter ! ') ;

20

// D s qu ' on nous donne un pseudo , on le stocke en variable


de session
socket . on ( ' petit_nouveau ' , function ( pseudo ) {
socket . set ( ' pseudo ' , pseudo ) ;
}) ;

21
22
23
24
25
26
27
28
29
30
31
32
33

}) ;

// D s qu ' on re oit un " message " ( clic sur le bouton ) , on


le note dans la console
socket . on ( ' message ' , function ( message ) {
// On r cup re le pseudo de celui qui a cliqu dans les
variables de session
socket . get ( ' pseudo ' , function ( error , pseudo ) {
console . log ( pseudo + ' me parle ! Il me dit : ' +
message ) ;
}) ;
}) ;

34
35

server . listen ( 8080 ) ;

Jespre avoir suffisamment comment ce code pour que vous puissiez vous y retrouver.
Je rappelle que cest une application trs basique pour essayer les fonctionnalits de socket.io. Elle ne fait rien dintressant ou de passionnant, cest
vous de vous amuser la bidouiller pour vous entraner. Faites-en quelque
chose de bien. . . Enfin quelque chose de plus utile que ce que jai fait au
moins.

92

COMMUNIQUER AVEC PLUSIEURS CLIENTS

En rsum
Socket.io est un module de Node.js qui permet vos visiteurs de communiquer en continu (en temps rel) avec le serveur lorsque la page est charge.
Socket.io se base notamment sur les WebSockets, une sorte de super AJAX .
Votre application peut tout moment solliciter le serveur sans recharger la page,
et linverse est aussi vrai : vos visiteurs peuvent recevoir des messages du serveur
tout moment !
Le serveur et le client senvoient des vnements (avec socket.emit()) et
coutent les vnements quils se sont envoys (avec socket.on()).
Pour que lapplication fonctionne du ct du client, vous devez charger la bibliothque de socket.io dans la page HTML envoye au visiteur. La bibliothque
est situe dans /socket.io/socket.io.js.
Le serveur peut envoyer un message tous les clients connects au serveur avec
socket.broadcast.emit().
Le serveur peut sauvegarder les donnes de session dun client avec set() et les
rcuprer avec get(). Pratique pour que le client nait, par exemple, pas besoin
de renvoyer son pseudo chaque vnement !

93

CHAPITRE 8. SOCKET.IO : PASSEZ AU TEMPS REL !

94

Chapitre

TP : le super Chat
Difficult :
Alors, socket.io vous plat ? Une fois que lon a russi le prendre en main, ce qui nest
pas vraiment compliqu quand on commence avoir lhabitude de Node.js, il faut avouer
quun grand nombre de possibilits soffre tout dun coup nous ! Imaginez tout ce que
vous pouvez commencer faire en temps rel ! Un Chat, des jeux, des outils collaboratifs
pour le travail, etc.
Parmi lensemble de ces possibilits, je pense que le Chat est de loin lapplication la plus
simple raliser tout en restant utile et efficace pour impressionner vos proches. Alors
allons-y !

95

CHAPITRE 9. TP : LE SUPER CHAT

Besoin daide ?
Vous tes perdus ? Vous ne savez pas par o commencer ?
Allons allons, si vous avez bien suivi le chapitre prcdent sur socket.io cela ne devrait
pas trop vous poser de problmes. Comme je suis (dcidment) trop sympa, je vais vous
donner quelques indices pour vous aider avancer.
Avant toute chose, regardez la figure 9.1. Elle vous montre quoi ressemblera notre
Chat.

Figure 9.1 Le Super Chat que vous allez devoir raliser


Ici jai volontairement ouvert deux fentres. Celle de gauche est connecte sous le pseudo
mateo21 et celle de droite sous le pseudo grard .
Je demande le pseudo avec une bote de dialogue lors de la connexion.
Jaffiche le pseudo de celui qui vient de se connecter tout le monde dans le
Chat (ex : grard a rejoint le Chat ! ).
Lorsque lon saisit un message, il est immdiatement affich dans le navigateur
sous le formulaire.
Bref, rien de bien compliqu ! Mais mme en vous basant sur les codes du chapitre
prcdent, il vous faudra travailler un petit peu et rflchir. Et cest exactement le plan
diabolique que jai en tte : vous faire travailler.
Posons-nous maintenant les bonnes questions. De combien de fichiers va-t-on avoir
besoin ? De toute vidence, je dirais trois :
Un fichier package.json qui dcrit les dpendances de votre projet Node.js.
Un fichier app.js pour lapplication ct serveur en Node.js
Un fichier index.html qui contiendra la page web et le code ct client de
96

BESOIN DAIDE ?
gestion du Chat.
Voici un petit peu daide pour raliser chacun de ces fichiers. Si vous vous sentez
laise, honntement, essayez de vous en passer, cest encore mieux (et au pire revenez
lire cette section si jamais vous coincez).

package.json
ce stade, vous devriez savoir crer un package.json les yeux ferms. Je ne vais pas
vous rexpliquer la syntaxe, si vous avez un trou de mmoire je vous laisse retourner
la section5.
Par contre, ct modules externes, de quoi va-t-on avoir besoin ? Voil ce que je
suggre (et que jutilise dans ma correction) :
socket.io : si vous laviez oubli, vous tes impardonnables.
express : tant qu faire, autant utiliser Express.js ds le dbut. On ne sen
est pas servi dans le chapitre de dcouverte de socket.io mais il nest pas trs
compliqu utiliser en combinaison de socket.io. Dans le code web suivant, on
vous explique comment lutiliser en combinaison dExpress.js.
ent : un tout petit module qui permet de protger les chanes de caractres
envoyes par les visiteurs pour transformer le HTML en entits. Ce qui permet
dviter que vos visiteurs senvoient du code JavaScript dans le Chat !


"How to use" sur le site SoB cket.io
Code web : 456713


Honntement, Express.js et ent ne sont pas obligatoires pour faire fonctionner le
Chat. On peut trs bien faire sans, mais jai choisi de les utiliser dune part pour
faciliter la maintenance du code (pour Express.js) et dautre part pour la scurit
(pour ent).

app.js
Elle devra renvoyer une page web lorsquon appellera le serveur. vous donc de renvoyer un fichier index.html vos visiteurs qui se connectent sur votre site. Avec
Express.js, la syntaxe est un petit peu diffrente mais aussi plus courte.
En plus de la page web classique , votre serveur Node.js devra grer les vnements
de socket.io. A priori je dirais que lon a besoin de nen grer que deux :
nouveau_client (vous lappelez comme vous voulez) : signale quun nouveau
client vient de se connecter au Chat. Devrait transmettre son pseudo pour pouvoir informer les clients avec des messages comme robert a rejoint le Chat ! .
message : signale quun nouveau message a t post. Votre rle, en tant que
serveur, sera tout simplement de le redistribuer aux autres clients connects avec
un petit broadcast. Tant qu faire, vous rcuprerez le pseudo du posteur dans
une variable de session.
97

CHAPITRE 9. TP : LE SUPER CHAT


En fin de compte, le fichier app.js nest pas trs gros ni trs compliqu. Plus je le
regarde, plus je le trouve mme tonnamment court et simple.

index.html
En fait, cest peut-tre le fichier qui demande le plus de travail et qui devrait vous donner (lgrement) du fil retordre. Vous allez devoir grer pas mal de code JavaScript
ct client.
Commencez par structurer une page HTML5 basique, avec un titre, un formulaire
compos dun champ de texte et dun bouton, et une <div> ou une <section> qui
contiendra les messages du Chat (par dfaut, elle sera vide).
vous ensuite dcrire le code JavaScript du client. Personnellement je lai plac
en bas de la page (pour des raisons de performances, cest une habitude prendre).
Jaurais aussi pu le mettre dans un fichier .js externe, mais je ne lai pas fait ici en
loccurrence.
Ce code devra :
Se connecter socket.io.
Demander le pseudo au visiteur lors du chargement de la page (via un prompt()
en JS, cest le plus simple que jaie trouv) et envoyer un signal nouveau_client.
Grer la rception de signaux de type nouveau_client envoys par le serveur.
Cela signifie quun nouveau client vient de se connecter. Affichez son nom dans
un message, comme par exemple Robert a rejoint le Chat ! .
Grer la rception de signaux de type message envoys par le serveur. Cela
signifie quun autre client vient denvoyer un message sur le Chat et donc quil
vous faut lafficher dans la page.
Grer lenvoi du formulaire lorsque le client veut envoyer un message aux autres
personnes connectes. Il vous faudra rcuprer le message saisi dans le formulaire en JavaScript, mettre un signal de type message au serveur pour quil le
distribue aux autres clients, et aussi insrer ce message dans votre propre page.
Eh oui, noubliez pas que le broadcast du serveur envoie un message toutes
les autres personnes connectes. . . except vous-mme. Il faut donc mettre
jour votre propre zone de Chat.
Je vous ai tellement prmch le travail que jen ai presque un coup de blues. . . Si vous
ny arrivez pas avec tout a. . . essayez plus fort !

Correction
Rien ne va plus, cest lheure de la correction !
Alors, comment sest passe la ralisation du Chat pour vous ? Vous ne devriez pas
avoir rencontr trop de problmes, ce TP tait une faon de reformuler un peu plus
proprement le chapitre prcdent dintroduction socket.io.
Mon projet est constitu de trois fichiers :
98

CORRECTION
package.json : la description du projet avec la liste de ses dpendances. Tout
projet Node.js qui se respecte en a un !
app.js : lapplication Node.js ct serveur qui gre les interactions avec les
diffrents clients.
index.html : la page web envoye au client qui contient du code JavaScript
pour grer le Chat ct client.

package.json
Notre package.json est trs simple :
1

2
3
4
5
6
7
8
9
10
11

" name " : " super - chat " ,


" version " : " 0 . 1 . 0 " ,
" dependencies " : {
" express " : " ~ 3 . 3 . 4 " ,
" socket . io " : " ~ 0 . 9 . 16 " ,
" ent " : " ~ 0 . 1 . 0 "
},
" author " : " Mateo21 < mateo21@email . com > " ,
" description " : " Un super Chat temps r el avec socket . io "

Comme je vous le disais (pour ceux qui ont lu mes astuces daide juste avant), jutilise
videmment socket.io, mais aussi Express.js (bien que ce ne soit pas obligatoire) et
ent (pour faire appel une fonction quivalente htmlentities() de PHP, afin de
scuriser les changes et dviter que les clients ne senvoient des codes JavaScript
malicieux).

app.js
Relativement court, le code serveur du Chat ntait pas le fichier le plus difficile crire
de ce TP !
1
2
3
4
5

var app = require ( ' express ') () ,


server = require ( ' http ') . createServer ( app ) ,
io = require ( ' socket . io ') . listen ( server ) ,
ent = require ( ' ent ') , // Permet de bloquer les caract res
HTML ( s curit quivalente htmlentities en PHP )
fs = require ( ' fs ') ;

6
7
8
9
10

// Chargement de la page index . html


app . get ( '/ ' , function ( req , res ) {
res . sendfile ( __dirname + '/ index . html ') ;
}) ;

11
12
13

io . sockets . on ( ' connection ' , function ( socket , pseudo ) {


// D s qu ' on nous donne un pseudo , on le stocke en variable
de session et on informe les autres personnes

99

CHAPITRE 9. TP : LE SUPER CHAT


socket . on ( ' nouveau_client ' , function ( pseudo ) {
pseudo = ent . encode ( pseudo ) ;
socket . set ( ' pseudo ' , pseudo ) ;
socket . broadcast . emit ( ' nouveau_client ' , pseudo ) ;
}) ;

14
15
16
17
18
19
20
21
22
23
24
25
26
27

}) ;

// D s qu ' on re oit un message , on r cup re le pseudo de


son auteur et on le transmet aux autres personnes
socket . on ( ' message ' , function ( message ) {
socket . get ( ' pseudo ' , function ( error , pseudo ) {
message = ent . encode ( message ) ;
socket . broadcast . emit ( ' message ' , { pseudo : pseudo ,
message : message }) ;
}) ;
}) ;

28

server . listen ( 8080 ) ;

29

Le dbut du fichier ne contient rien dextraordinaire : quelques appels des modules,


la gestion de lindex ( / ) o on renvoie index.html. . . Non vraiment, plus simple,
tu meurs.
En-dessous, nous avons toute la gestion des messages temps rel avec socket.io. En
fait, on ne gre que deux types de messages diffrents :
nouveau_client : envoy par un nouveau client qui vient de charger la page. Il
contient son pseudo en paramtre. Jai choisi de lencoder (avec ent.encode())
par scurit. Ainsi, si le visiteur met du JavaScript dans son pseudo, on est
par ! Ensuite je nai plus qu sauvegarder ce pseudo dans une variable de
session.
message : envoy par un client qui veut transmettre un message aux autres personnes connectes. Dans un premier temps, je rcupre son pseudo que javais
conserv en variable de session. La fonction de callback est appele ds que
le serveur a rcupr le pseudo (a ne prend pas trs longtemps en pratique,
mais vous savez que Node.js dteste les fonctions bloquantes !). Ds quon a
le pseudo, on encode le message (toujours par scurit) et on le broadcast avec
le pseudo. Pour envoyer plusieurs donnes dans un seul paramtre, je les encapsule dans un objet JavaScript, do le code {pseudo: pseudo, message:
message}.
Cest tout ce que le serveur a besoin de faire !

index.html
OK, le code du client est un poil plus compliqu. Mais alors juste un poil honntement. Le voici tout de go, on le commente juste aprs, promis :
1
2

<! DOCTYPE html >


< html >

100

CORRECTION
3
4
5
6
7
8
9
10
11
12
13

< head >


< meta charset = " utf - 8 " / >
< title > Super Chat temps r el ! </ title >
< style >
# zone_chat strong {
color : white ;
background - color : black ;
padding : 2px ;
}
</ style >
</ head >

14
15
16

< body >


<h1 > Le super Chat temps r el ! </ h1 >

17
18
19

20
21

< form action = " / " method = " post " id = " formulaire_chat " >
< input type = " text " name = " message " id = " message "
placeholder = " Votre message ... " size = " 50 "
autofocus / >
< input type = " submit " id = " envoi_message " value = "
Envoyer " / >
</ form >

22
23

< section id = " zone_chat " >

24
25

</ section >

26
27
28
29

< script src = " http :// code . jquery . com / jquery - 1 . 10 . 1 . min .
js " > </ script >
< script src = " / socket . io / socket . io . js " > </ script >
< script >

30
31
32

// Connexion socket . io
var socket = io . connect ( ' http :// localhost : 8080 ') ;

33
34
35
36
37

// On demande le pseudo , on l ' envoie au serveur et


on l ' affiche dans le titre
var pseudo = prompt ( ' Quel est votre pseudo ? ') ;
socket . emit ( ' nouveau_client ' , pseudo ) ;
document . title = pseudo + ' - ' + document . title ;

38
39
40
41
42

// Quand on re oit un message , on l ' ins re dans la


page
socket . on ( ' message ' , function ( data ) {
insereMessage ( data . pseudo , data . message )
})

43
44
45

// Quand un nouveau client se connecte , on affiche


l ' information
socket . on ( ' nouveau_client ' , function ( pseudo ) {

101

CHAPITRE 9. TP : LE SUPER CHAT


46

})

47

$ ( '# zone_chat ') . prepend ( ' <p > < em > ' + pseudo + '
a rejoint le Chat ! </ em > </p > ') ;

48

// Lorsqu ' on envoie le formulaire , on transmet le


message et on l ' affiche sur la page
$ ( '# formulaire_chat ') . submit ( function () {
var message = $ ( '# message ') . val () ;
socket . emit ( ' message ' , message ) ; // Transmet le
message aux autres
insereMessage ( pseudo , message ) ; // Affiche le
message aussi sur notre page
$ ( '# message ') . val ( ' ') . focus () ; // Vide la zone
de Chat et remet le focus dessus
return false ; // Permet de bloquer l ' envoi "
classique " du formulaire
}) ;

49
50
51
52
53
54
55
56
57

// Ajoute un message dans la page


function insereMessage ( pseudo , message ) {
$ ( '# zone_chat ') . prepend ( ' <p > < strong > ' + pseudo
+ ' </ strong > ' + message + ' </p > ') ;
}
</ script >
</ body >
</ html >

58
59
60
61
62
63
64

La partie un peu complexe se situe dans le code JavaScript la fin du fichier. On y


trouve tout le ncessaire ct client pour grer le Chat :
La connexion socket.io.
La demande de son pseudo au client et lenvoi au serveur via un signal de type
nouveau_client. Petit bonus, je me suis permis dafficher le pseudo dans le
<title> de la page afin quil apparaisse dans les onglets de mon navigateur. Vu
que pour mes tests jouvre plusieurs onglets sur ma machine, a maide me
souvenir qui est qui !
La rcupration du signal message envoy par le serveur. Dans ce cas, jinsre
le message dans la zone #zone_chat de la page. Jai choisi de crer une fonction
pour a car jai aussi besoin de cette fonctionnalit au moment de lenvoi du
formulaire.
La rcupration du signal nouveau_client o jaffiche XXX a rejoint le
Chat ! .
La gestion de lenvoi du formulaire. Peut-tre la partie la plus dlicate. Il faut
rcuprer le message saisi par le client, lenvoyer au serveur et linsrer dans
notre page (car le serveur transmet le message tout le monde sauf nous !). Jen
profite aussi pour vider la zone de texte, remettre le focus dessus. . . et bloquer
lenvoi classique du formulaire. Le return false est indispensable si on ne
veut pas que la page se recharge suite lenvoi du formulaire. En fait, return
false est quivalent la fonction de jQuery preventDefault().
102

CORRECTION
Enfin, la fonction insereMessage() qui est ma foi trs simple. Elle rajoute le
message quon lui envoie avec le pseudo dans la zone de Chat, au dbut. La
fonction prepend() fait partie de jQuery, je ne linvente pas.
Jai choisi dutiliser jQuery dans mon code pour des raisons pratiques, mais vous
pouvez bien entendu faire tout a en pur JavaScript si vous en avez envie (ou avec
une autre bibliothque).
En fait, le code JavaScript ct client est peut-tre le plus gros. La partie Node.js
serveur est, comme vous le voyez, trs simple : on se connecte, on envoie des signaux,
on rcupre des signaux. . . et cest tout !

Tlcharger le projet
Vous avez tout le ncessaire prcdemment, mais si vous voulez vraiment un fichier .zip
tout prt, je vous propose de le tlcharger sur le code web suivant :


Tlcharger le fichier .zip
B
Code web : 647648


Petit rappel : il faut faire un npm install pour installer les dpendances
avant de lancer le projet avec node app.js !

Allez plus loin !


Vous voulez vous entraner encore plus avec socket.io ? Voici de quoi vous occuper
pendant un moment (par ordre approximatif de difficult croissante) !
Affichez un message aux autres personnes lors de la dconnexion dun client.
Permettez aux clients de changer leur pseudo en plein milieu dune session de
Chat.
Et si vous rajoutiez des boutons sur la page pour faire jouer des sons prchargs distance ? Un bon petit ding pour que les autres clients endormis se
rveillent ?
Essayez de sauvegarder les messages en mmoire sur le serveur pour quon retrouve la liste des derniers messages changs lorsquon se connecte ! Vous pouvez sauvegarder les informations juste en mmoire vive comme on a appris
le faire. . . ou essayer carrment de coupler Node.js une base de donnes
MySQL, MongoDB, redis, etc.
Et si vos clients pouvaient senvoyer des images en plus du texte ?
Et si malgr tout a vous vous ennuyez encore, reprenez le code du prcdent TP7 pour
en faire une todolist partage en temps rel entre plusieurs clients ! Lajout ou la
suppression dune tche sera automatiquement rpercut auprs des autres clients !

103

CHAPITRE 9. TP : LE SUPER CHAT

104