TP2 HTML5 2011-2012 M2 Miage

De $1

Version de 11:28, 20 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

Intégration de l'aspect "multi-participants"

Nous allons maintenant intégrer à notre projet un chat multi-participants utilisant l'api Web Socket. Pour ce faire, le code HTML5 à ajouter sera très simple, mais il faut avant tout installer un serveur web comprenant le protocole des Web Sockets. La page des ressources HTML5 recense des serveurs qui supportent cette feature (la liste est incomplète), mais pour ce TP nous allons nous servir d'un serveur embarqué très léger, qui a beaucoup de succès en ce moment, de par sa grande souplesse. Il s'agit du serveur Node.JS qui est écrit en Python, et qui permet d'écrire des applications web directement en javascript. il inclut l'interpréteur javascript le plus rapide du moment, nommé V8 (le même qu'il y a dans le navigateur Chrome). Le fait de pouvoir écrire des applications côté serveur en javascript est avantageux car les échanges de paramètres/valeurs de retour entre clients javascript s'exécutant dans le navigateur et appli serveur en javascxript sont naturelles.

Un serveur web embarqué n'est pas censé tenir une grosse charge, fournir des services évolués de maintenance/déploiement/sécurité, etc... Il se trouve à l'opposé de ce que l'on appelle des "serveurs d'application" comme JBoss, Glassfish, WebSphere, Oracle Application Server, etc... Ici on veut un serveur qui se lance en une seconde, qui occupe très peu de mémoire, etc... Dans un précédent cours on a utilisé comme serveur embarqué le serveur Grizzly (qui est inclut dans GlassFish) mais nous n'avons pas réussi simplement à faire tourner une implémentation des WebSocket dessus (pourtant une telle implémentation existe, dans les night builds, etc.. mais c'est encore très nouveau...). Au passage, ce que j'ai dit au début de ce paragraphe n'est pas forcément vrai : nodeJS est ultra-performant en ce qui concerne la gestion de la charge car il utilise un modèle de programmation "par événement" et non pas un modèle classique à base de Threads. On en reparlera.

Installer le serveur Node.JS et le tester !

La procédure est simple : allez sur le site 

  1. Allez sur le site officiel de Node.JS : http://www.nodejs.org
  2. Suivez les instructions ! Cliquez sur "download" et utiliser un installeur.
  3. Ajouter dans la variable PATH le chemin où nodejs a été installé (par ex C:\Program Files(x86)\nodejs),
  4. Ouvrez une fenêtre de terminal et tapez "node --version" ça doit afficher la version courante (0.6.8 à l'heure où j'écris ce TP). Si cela dit "command not found", alors vous n'avez pas bien positionné la variable PATH. Vérifiez, re-ouvrez une fenêtre de terminal, re-testez.

Testez maintenant une petite application, par exemple un micro serveur HTTP. Créez le fichier test.js suivant :

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');

et que vous sauvez quelque part . Puis lancez (depuis la ligne de commandes) la commande suivante :

node test.js


Vous venez de lancer un serveur qui répond à des requêtes http sur l'URL suivant : http://localhost:8124 Essayez donc d'ouvrir cet URL avec un navigateur web ! Cela doit afficher :

Snap5.jpg

Le serveur est lancé !

Snap6.jpg

Le navigateur a eu une réponse ! Vous voyez le petit code javascript du fichier test.js, c'est déjà un serveur ! C'est cela, la magie d'un serveur embarqué !

Ajout de librairies pour les WebSockets

Les librairies pour nodeJS s'appellent des "modules". Il existe de nombreuses manières de les installer (notamment via le réseau et de manière globale au travers de  la commande "npm" ou Node Package Manager), mais nous allons faire le plus simple possible : les mettre dans un répertoire "node_modules" dans le répertoire où se trouvera votre TP.

  • Desarchivez cette archive qui contient les modules nodeJS nécessaires aux websockets et à la manipulation simple d'un serveur web HTTP. Il s'agit des modules socket.io, express et nowJS : ChatNowJs.zip (1.8 Mo). Ceci doit créer un répertoire "ChatNowJS" qui contiendra deux exemples de chat ainsi que les modules dont on vient de parler.
  • Testez le chat le plus simple en lançant la commande "node simpleChat_server.js" et en ouvrant http://localhost:8080 dans un navigateur web, ouvrez deux onglets avec la même adresse.
  • SI CELA NE MARCHE PAS :
    1. installez sur votre machine VC++ runtime voici le lien : http://www.microsoft.com/download/en...s.aspx?id=5555, les plus curieux pourront lire :  http://blog.nowjs.com/running-nowjs-natively-on-windows pour comprendre pourquoi cela est nécessaire.
  • Regardez bien le code source htlml et js de cet exemple. La lirairie NowJS (voir  http://nowjs.com/) permet de partager des objets (attributs et methodes) entre le code qui tourne dans le navigateur et le code qui tourne sur le serveur. Magique ! Cette librairie utilise en coulisse la librairie socket.io (voir  http://www.socket.io) qui permet de faire des websockets avec des systèmes de rétro-compatibilité si le navigateur ne supporte pas les websockets.
  • Testez et étudiez le chat "multiroom" en lançant "node multiroomchat_server.js" et en ouvrant localhost:8080
  • Ceux qui veulent en savoir plus peuvent regarder les guides, démos et tutoriaux sur le site de nowJS.

Ajout de la fonctionnalité "dessin à plusieurs" dans votre logiciel de dessin

Intégration du chat dans le paint et utilisation du chat pour broadcaster les ordres de dessin

Vous allez maintenant utiliser le chat que nous venons d'étudier pour transférer des objets d'un client vers tous les autres. Pour cela, vous pouvez utilisez les fonctions de sérialisation de JSon de javascript et de jQuery, comme indiqué dans le TP1.

Méthode conseillée :

  1. Intégrez tel quel le  chat dans la page du logiciel paint et testez-le avec le même serveur que pour les tests précédents !!!! Rajoutez les lignes de javascript qu'il faut à la fin du fichier js inclut par la page html. Rajoutez dans la page html la ligne qui permet d'utiliser jQuery (on l'utilise dans les exemple, partout où il y a des "$"), et rajouter vers la fin du fichier les lignes html qui crée la zone de texte, le bouton, etc.
// à la fin du fichier js inclut par le paint... Note ici on a besoin de jQuery. rajouter en tête du fichier html la ligne qui inclut JQuery
$(document).ready(function(){
  now.receiveMessage = function(name, message){
    $("#messages").append("<br>" + name + ": " + message);
  }
  
  $("#send-button").click(function(){
    now.distributeMessage($("#text-input").val());
    $("#text-input").val("");
  });

  now.name = prompt("What's your name?", "");

});
  1. Envoyez ensuite via le chat les événements de dessin sous forme de texte, et vérifiez qu'ils transitent bien ! Par exemple "j'ai dessiné une ligne de telle coordonnées à telles coordonnées", vérifiez que le texte a bien transité vers tous les clients, 9a se fait en général juste avant les img_update() qui effectuent le dessin.
  2. Maintenant, essayez d'envoyer un objet Javascript sérialisé en JSon, et décodez-le à l'arrivée, affichez un message dans le texte du chat correspondant à l'objet décodé. rappel : lorsque nous transmettrons réellement ces objets, on les mettra au format JSON à l'aide de la fonction JSON.stringify(message) de JavaScript, côté récepteur, on transformera les objets JSON reçus en objets javascript à l'aide de la fonction http://api.jquery.com/jQuery.parseJSON/ de jQuery (ce qui est plus simple qu'utiliser la fonctuon JavaScript pure JSON.parse(jsonObject)
  3. Interprétez-les quand ils sont reçus et provoquez le dessin côté récepteur du dessin effectué par l'envoyeur. Vous aurez peut être besoin de modifier un peu le format de vos objets pour qu'ils soient plus faciles à manipuler.

Exemple de transformation objet javascript-> json et envoie par websocket

var objJSON = { "type" : 'line', "x0" : tool.x0, "y0" : tool.y0,"x1" : ev._x, "y1" : ev._y };
var msgJSON = JSON.stringify(objJSON);
now.distributeForm(msgJSON);

JSON -> objet javascript

// lorsqu'on reçoit un message en JSON
now.receiveForm = function(name, msgJSON){
objJSON = jQuery.parseJSON(msgeJSON);
...
if(objJSON.type == "Line"){