##### Socket.io ##### Maintenant que nous avons une base avec un ``Hello World``, nous allons rajouter une fonctionnalité pour que vous puissiez mieux comprendre le fonctionnement de ``socket.io`` dans cette application. .. warning:: Dans cette section, nous verrons juste comment intégrer ``socket.io`` à notre ``Hello World`` pour que l'application reste bien structurée (le fonctionnement général de ``socket.io`` étant expliqué sous ``pré-requis``). Code côté serveur ----- Tout d'abord, nous allons créer un nouveau fichier nommé ``socket.js`` que nous mettrons dans le dossier ``serveur``. .. only:: html .. code-block:: tree :emphasize-lines: 4 . └── serveur ├── routes.js └── socket.js .. only:: latex .. code-block:: sh :emphasize-lines: 4 . `-- serveur |-- routes.js `-- socket.js Dans ce fichier, nous écrivons le code suivant : .. captionup:: ./serveur/socket.js .. code-block:: javascript // comme dans le fichier routes.js, la fonction principale est lancée depuis app.js // nous passons le paramètre io, qui contient le module socket.io, depuis app.js exports.f = function(io) { /* cette fonction de callback s'exécute à chaque fois qu'un client émet l'événement "connection" */ io.on('connection', function (socket) { /* lorsque le client effectue un socket.emit('bouton_client'), cette fonction s'exécute */ socket.on('bouton_client', function(){ console.log('Le client a cliqué sur le bouton !') }); }); } Nous exécutons un ``require`` pour que ``app.js`` charge le module ``socket.io`` : .. captionup:: ./app.js .. code-block:: javascript var io = require('socket.io')(server); Nous chargeons le fichier ``socket.js`` : .. captionup:: ./app.js .. code-block:: javascript var socket = require('./serveur/socket.js'); Puis, nous demandons à ``app.js`` d'exécuter la fonction que nous venons de créer en lui passant le module ``socket.io`` : .. captionup:: ./app.js .. code-block:: javascript socket.f(io); Votre fichier ``app.js`` devrait alors ressembler à ceci : .. captionup:: ./app.js .. code-block:: javascript var http = require('http'); var path = require('path'); var express = require('express'); // nous faisons appel à expressJS en tapant app.nom_de_la_fonction() var app = express(); var server = http.Server(app); var io = require('socket.io')(server); var routes = require('./serveur/routes.js'); var socket = require('./serveur/socket.js'); // appel de la fonction qui se trouve dans "routes.js" routes.f(app, __dirname); // appel de la fonction qui se trouve dans "socket.js" socket.f(io); server.listen(8888); .. important:: Il est essentiel de respecter l'ordre des ``require``. Comme vous pouvez le constater, certains modules dépendent d'autres modules. C'est par exemple le cas de ``socket.io`` qui a besoin de la variable ``server``, qui nécessite elle-même la variable ``app`` d'``expressJS`` pour fonctionner correctement. Si vous inversez l'ordre de ces instructions, des erreurs peuvent survenir. Code côté client ----- Maintenant que le serveur peut faire fonctionner ``socket.io``, il reste quelques modifications à effectuer du côté client. Nous commençons par ajouter une ligne au début du fichier ``general.js`` : .. captionup:: ./static/js/general.js .. code-block:: javascript var socket = io.connect('http://' + window.location.host); .. tip:: ``window.location.host`` contient le nom de domaine avec le port sur lequel est connecté le client. En l'occurence, cette commande équivaut à ceci : .. code-block:: javascript var socket = io.connect('http://localhost:8888') Ensuite, nous ouvrons un nouveau fichier pour séparer le ``javascript`` du ``HTML`` sur le côté client. .. only:: html .. seealso:: Mais pourquoi ne pas utiliser ``general.js`` ? .. only:: latex .. hint:: Mais pourquoi ne pas utiliser ``general.js`` ? Parce que ce fichier contient des fonctions ``javascript`` qui s'appliquent à toutes les pages de l'application. Dans notre cas, le ``socket.emit`` ne sert qu'à une seule page, ``index.ejs``. Il faudra donc plutôt créer un fichier du nom de ``index.js`` : .. only:: html .. code-block:: tree :emphasize-lines: 5 . └── static └── js ├── general.js └── index.js .. only:: latex .. code-block:: sh :emphasize-lines: 5 . `-- static `-- js |-- general.js `-- index.js Dans ce fichier, nous rédigeons une fonction avertit le serveur que le client a interagi avec la page web : .. captionup:: ./static/js/index.js .. code-block:: javascript function avertir_serveur() { socket.emit('bouton_client'); } Ensuite, nous ajoutons un bouton qui exécutera cette fonction lorsqu'il sera cliqué sur la page ``index.ejs`` : .. captionup:: ./views/index.ejs .. code-block:: html N'oublions pas de faire référence au fichier ``index.js`` que nous venons de réaliser en ajoutant cette ligne juste avant la fin de la balise ``head`` : .. captionup:: ./views/index.ejs .. code-block:: html Notre page ``index.ejs`` contient alors contenir ceci : .. captionup:: ./views/index.ejs .. code-block:: guess
<% include balise_head %> <% include barre_navigation %>Hello World !