![]() |
![]() |
TP2 : un paint HTML5, multi-participants, avec support de la persistanceDe $1Table des matières
Préambule : ce TP sera à rendre et sera noté !Ne pleurez pas, il n'est pas à rendre cette fois-ci mais il doit être terminé avant que le TP No 4 ne commence ! C'est-à-dire que vous avez cette séance + la séance de la semaine prochaine pour le terminer. Il sera ramassé à midi vendredi 18/2. Bien entendu, vous êtes libres de "vous amuser" en ajoutant plein plein de trucs rigolos qui ne sont pas prévus, dans le petit logiciel que vous allez développer ! Plus cela ne sert à rien, mieux c'est ! Pour ceux qui ne sont pas à l'aise en javascript et qui ne connaissent pas JQuery
IntroductionDans ce TP vous allez suivre un petit tutorial qui explique pas à pas comment écrire un programme de type "paint" en HTML5 + javascript, mais pour que cela soit amusant, on va lui ajouter un support multi-participants synchrone + un petit chat. Ce programme utilise le widget "canvas" de HTML5, qui permet de faire beaucoup de choses (vous le verrez en suivant les liens vers les démos et autres tutoriaux sur les canvas. On le présente comme un concurrent de flash...). Par la suite nous l'intégrerons à l'application facebook du TP1. Et oui, cela devrait être facile car on ne va faire que du HTML5 et du javascript !
Travail à faireUn peu de lecture
Un peu de codageVous avez le choix de l'éditeur pour les fichiers html et javascript, Netbeans est assez gros comme logiciel mais il supporte très bien la syntaxe HTML5 et javascript (avec auto-complétion, indentation automatique etc). Mais je l'avoue j'ai surtout utilisé un mélange de xemacs/cygwin et de ultraedit... !
Un peu de réflexion
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... L'an dernier on avait 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...) Travail à faire : installer le serveur Node.JS et le tester !Pour les linuxiens ou les macs OSiens, vous êtes sous un Unix, tout devrait rouler, enfin, je suppose. Nous avons testé sous mac OS et l'installation a pris 5 minutes. Pour les Windowsiens, le chemin est plus long, déjà il faut avoir installé cygwin, et ensuite il faudra passer une vingtaine de minutes à installer/builder la bête ! Voici les instructions :
Une fois que vous aurez réussi à installer le serveur, vous devriez avoir dans le PATH la commande 'node' exécutable. Elle permet d'exécuter simplement une application web. Par exemple, si vous créez un fichier test.js qui contient : 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 (je l'ai mis dans ~/node_apps sous cygwin). Puis lancez (depuis cygwin ou un shell) 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 : Le serveur est lancé ! 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é ! Test d'une application qui implémente un serveur supportant le protocole WebSocketNous allons maintenant rajouter à Node.JS le support pour le protocole des WebSockets (les URLs seront donc des ws://localhost:8xxx et pas des http://localhost:8xxx). Pour cela nous allons télécharger du code js qui implémente ce protocole. Il existe plusieurs implémentations, mais nous en avons choisi une qui fonctionne bien, et qui est relativement simple à mettre en oeuvre. Nous vous fournissons un zip prêt à l'emploi (mais croyez-moi on a bien galéré pour retrouver tous les morceaux sur github, il s'agit de cette implémentation : https://github.com/miksago !) :
Récuperez cette archive, désarchivez-là quelque part (par exemple, dans le même répertoire que là où vous aviez mis test.js), et faites un cd dans le sous-répertoire examples, puis lancez pour commencer la commande "node echo-server.js", cela va lancer un serveur sur le port 80, qui va juste gérer des connexions via web socket et faire l'echo à tous les clients connectés de ce que le serveur a reçu.
Regardez maintenant les sources du fichier client.html, oubliez le barratin de présentation et focalisez-vous sur la partie qui ouvre le web socket. Va variable "conn" est le web socket, et on lui attache 4 fonctions de callback. La plus importante est onmessage qui sera invoquée chaque fois qu'un message arrive. var connect = function() { if (window["WebSocket"]) { host = "localhost:8000"; conn = new WebSocket("ws://"+host+"/test"); conn.onmessage = function(evt) { log(evt.data); }; conn.onerror = function() { log("error", arguments); }; conn.onclose = function() { log("closed"); }; conn.onopen = function() { log("opened"); }; } }; Pour envoyer un message, c'est encore plus simple (c'est la 4ème ligne la plus importante !) document.getElementById("send").addEventListener("click", function(e) { if (conn) { setTimeout(function() { conn.send("test message"); log("<"+conn.id+"> "+"test message"); }, 0); } e.preventDefault(); return false; }, false); Quand au code du serveur, on croit rêver, c'est ultra-simple ! On crée un server (ligne 4), puis on ajoute des écouteurs (les paramètres "connection", "message", "error", "disconnected" représentant le type de message reçu). Regardez donc le code de l'écouteur lorsqu'on reçoit un message : conn.broadcast(...), qui renvoie le message à tous les clients connectés. Pour écrire à un seul client : conn.emit(...) var sys = require("sys") , ws = require('../lib/ws/server'); var server = ws.createServer({debug: true}); // Handle WebSocket Requests server.addListener("connection", function(conn){ conn.send("Connection: "+conn.id); conn.addListener("message", function(message){ conn.broadcast("<"+conn.id+"> "+message); if(message == "error"){ conn.emit("error", "test"); } }); }); server.addListener("error", function(){ console.log(Array.prototype.join.call(arguments, ", ")); }); server.addListener("disconnected", function(conn){ server.broadcast("<"+conn.id+"> disconnected"); }); server.listen(8000); Maintenant regardons l'exemple du chat multi-participants :Toujours dans le même répertoire :
Voilà ! Tout le monde chatte gaiement ! Ajouter le chat dans le programme paint !Ah ah !!!!! Là, mes enfants, c'est à vous de jouer !!!!!
Un peu de persistenceLes apis WebStorage et Web SQLNous allons maintenant sauvegarder nos dessins dans une base de donnée SQL du navigateur, le tout depuis du javascript ! Bien que cela ne fasse plus partie officiellement de la norme HTML5, la plupart des gros navigateurs intègrent une BD SQL légère et supportent l'api web SQL data storage (Chrome, Safari, Opera). Commencez par regarder l'exemple du cours et par le faire fonctionner : http://slides.html5rocks.com/#web-sql-db. Sous chrome, si vous utilisez le raccourci ctrl-shift-i (sous windows, sous mac, faire command-alt-i, sous linux, cherchez donc !), vous verrez la console des développeurs webkit Regardez maintenant le source du transparent correspondant (vous pouvez le retrouver en faisant "view source" et en cherchant le mot-clé "SQL"). On trouve en particulier le code qui crée la base et la table : function createTable() { db.transaction(function(tx) { tx.executeSql("CREATE TABLE Table1Test (id REAL UNIQUE, text TEXT)", [], function(tx) { log.innerHTML = '"Table1Test" created!' }, onError); }); } Travail à faire
Modalités de rendu du TPVous travaillerez en binome. Vous mettre votre projet dans un répertoire portant vos noms de binome. Dans ce répertoire vous mettrez le répertoire qui contient les fichiers html et js nécessaires (par exemple, le répertoire WebSocket avec en plus le fichier paint.html dans le répertoire des exemples). Vous ajouter un petit Readme.txt et une ou deux photos d'écrans pour pimenter la sauce. Puis vous packagez le tout dans un fichier zip qui porte lui aussi le nom de votre binome. Nous viendront vous voir avec notre clé USB bien affutée à la fin de la séance du 18/2. Le TP sera noté et comptera pour 30% de la note finale. |
Powered by MindTouch Deki Open Source Edition v.8.08 |