Thursday, 22 July 2010

Un serveur WebSocket en Python

Bonjour les gens !!

Bon je sais, ça fait un bail, mais voila, c'est ça aussi la vie d'un blog, y a des hauts et des bas ! 

Aujourd'hui, j'vais vous parler de deux choses, qui sont liées. Tout d'abord, je lance un nouveau projet de jeu vidéo, un jeu web (ou browser game) pour être précis. Mon annonce sur le Site du Zéro présente bien le projet, je vous invite donc à aller la lire si vous êtes intéressé. 

Pour résumer, le jeu sera un jeu de stratégie en tour par tour, faisant s'affronter des unités typées médiéval (infanterie, archerie, chevalerie) sur une carte constituée de cases hexagonales, le tout en vue 2d isométrique. Le but est de faire un jeu simple d'accès, permettant à un joueur de faire une partie rapidement, juste avec son navigateur (sans nécessiter de plugin quelconque), et sans avoir à gérer des tas de trucs avant de se lancer dans la partie. 

Voir le Game Concept Document de Fightly

Techniquement, le jeu utilisera HTML, CSS et JavaScript pour la partie client, PHP pour la génération des pages et Python pour le serveur de gestion des parties. L'intérêt est l'utilisation des récentes WebSockets, actuellement implémentées dans Chrome et Chromium uniquement, mais pour lesquelles il existe des fallback. Je vous ferai bien une présentation détaillée de l'utilisation des WebSocket, et pourquoi c'est top moumoute, mais non. J'vais plutôt vous balancer quelques liens intéressants sur le sujet : 

Et on en arrive au deuxième point : dans le cadre de ce projet, j'ai développé un début de serveur permettant de communiquer avec une page web via les WebSockets. Chez le client, on a un code JavaScript assez classique, qui utilise la très simple interface WebSocket. Et du côté du serveur, j'ai donc développé un serveur en Python qui créé les connexions, reçoit les messages des clients, les analyse et les traite comme il faut, puis renvoie aux clients le nouvel état du "monde". C'est assez étonnant de simplicité, d'autant que j'ai commencé à apprendre Python environ 3 jours avant de réussir à faire ce serveur. Bon faut avouer que je ne suis pas parti de rien, j'ai repris le code de Eneko Alonso, donné sur son blog : More WebSockets, now with Python!

Tout ça pour en venir au point intéressant : j'ai décidé de partager avec vous la partie qui gère les WebSockets. Elle est orientée objet, utilise un thread pour chaque client (donc pour chaque connexion), et vous permet assez simplement d'ajouter votre propre comportement lors de réception d'un message. 

Voir le projet python-websocket-server sur GitHub

Bon, c'est le premier truc que je fais en Python, donc y a surement des erreurs. Mais j'espère que vous saurez me les faire remarquer ! :) Je sais par exemple que je ne gère par l'arrêt du serveur par interruption, et que c'est un problème car le serveur ne s'arrête pas tant que tous les clients ne sont pas déconnectés (puisqu'il y a encore des thread en cours de fonctionnement). Je sais également que je pourrais faciliter l'utilisation du code en ajoutant un mécanisme de fonction callback, mais je sais pas encore faire ça en Python, donc ça viendra plus tard ! ^^

Actuellement, le code est celui d'un chat très simple. A chaque fois qu'un client envoie un message, le serveur le renvoie à tous les clients. Pour tester, lancer le server.py dans une console, et accédez à la page index.html depuis votre localhost. Ouvrez cette dernière dans plusieurs onglets, et envoyer un message dans l'un d'eux. Vous devriez voir apparaitre le message sur toutes les autres fenêtres quasiment instantanément. 

Pour ajouter votre propre comportement, modifiez le code de la fonction onreceive de la classe WebSocketClient (websocketclient.py). Il est aussi possible que vous ayez à changer la configuration du serveur dans le fichier config.py. 

J'espère que ce code pourra être utile à certains d'entre vous. Et bien sur, si vous avez des questions, n'hésitez-pas ! Passez à ma grotte ! Laissez-moi un message ! 

Wednesday, 7 April 2010

Minimiser ses fichiers CSS et JS, quelles solutions ?

Bonjour à tous ! 

Je profite d'un article de Prélude sur l'optimisation par compression ou par minimisation pour présenter les différents moyens existants pour minimiser (ou minifier en mauvais français) les fichiers CSS et JS de votre site. 

Performances des pages web

Mais déjà, pourquoi faudrait-il minimiser vos fichiers ? Au débuts de l'Internet, on avait des débits ridicules, et il fallait donc réduire au maximum le poids de nos pages. Et puis, l'ADSL est arrivé et on a petit à petit oublié les limitations liées au débit. Ce fut une erreur, parce que les internautes détestent attendre. Aujourd'hui, on entend dire que Google va prendre en compte le temps de chargement des pages pour ses algorithmes de recherche. C'est une bonne chose, car cela ramène la question de la vitesse de chargement sur le devant de la scène du développement web. 

Vous trouverez déjà beaucoup d'articles sur le web qui parlent de performance. Il y a des sites entièrement dédiés à ce pan du développement, et Google saura vous les indiquer. Je ne vais donc pas répéter ce que d'autres expliquent mieux que moi, mais je vais vous présenter une façon d'améliorer ses performances que j'apprécie. 

Compression à la volée

Si vous suivez mon blog et mes projets, vous avez vu mon plugin Minifier pour Atomik Framework. Ce plugin permet de minimiser ses fichiers CSS au moment où ils sont demandés par l'internaute. Plusieurs intérêts à ça : réduire le nombre de requêtes HTTP, réduire la taille des fichiers CSS. Au final, l'utilisateur télécharge beaucoup moins de données inutiles, pour le même résultat affiché. 

J'avais découvert cette technique sur le blog de LateralCode (Stunningly Simple CSS Minifier), et j'ai vite accroché. Je ne suis pas fan de la minimisation avant l'envoi des fichiers sur le serveur, parce que ça oblige à avoir deux versions du code (une normale, une réduite), et surtout, ça oblige à re-minimiser les fichiers à chaque changement. Comme tout développeur, je suis faignant, donc ça ne me convient pas. 

La technique proposée par LateralCode consiste donc en une compression via un script PHP, donc directement sur le serveur. On spécifie les fichiers CSS à charger, le script PHP les ouvre, les compresse et les concatène, puis renvoie le résultat. C'est ce que j'ai fait avec Minifier, en ajoutant une fonctionnalité de mise en cache. 

Mise en pratique

Prenons un exemple pratique pour bien voir tout l'intérêt de ce système : j'ai un site avec trois pages. Sur chaque page, j'ai trois fichiers CSS communs : reset.css (un système de reset CSS comme celui d'Eric Meyer), global.css (qui définit des attributs sur mes éléments HTML, comme img { border: none; }) et main.css (qui définit le design général des pages). Ensuite, sur chaque page je charge un fichier particulier, correspondant au nom de la page, qui définit le style des éléments spécifiques à cette page. J'ai donc, sur chaque page, au moins 4 fichiers CSS différents. Ceci me permet d'avoir des fichiers proprement séparés, un code CSS réparti et donc mieux organisé, etc. Seulement, au niveau des performances, c'est pas le top, car 4 requêtes HTTP sont nécessaires pour charger le CSS de la page. 

L'utilisation du plugin Minifier, ou de tout autre système similaire, permet de faire ceci : 

  • génération du nom du fichier cache correspondant aux fichiers CSS demandés
  • si le fichier cache existe, et que les fichiers CSS sont moins récents que le fichier cache, on renvoi directement le fichier cache
  • sinon, compression de chaque fichier séparément (retrait des espaces, des retours à la ligne, des commentaires... )
  • concaténation des fichiers
  • enregistrement du résultat dans un fichier cache
  • renvoi du fichier cache

Au final, on aura donc sur notre serveur des fichiers toujours aussi propres, et on aura en cache un fichier CSS compressé par page. Les internautes ne reçoivent donc qu'un fichier compressé correspondant au code de la page visitée. 

Problématiques

Les systèmes de compression à la volée existent depuis quelques temps, mais je ne crois pas qu'ils soient très connus. L'inconvénient majeur, c'est le temps de compression et de mise en cache nécessaire quand on change un des fichiers. Cependant, la mise en cache permet de diminuer très fortement l'impact de ce comportement. Et puis, quand vous faites un changement sur votre site, vous vérifiez bien toutes les pages, non ? ;-)

Il y a cependant un gros reproche fait à la compression des fichiers en général : ça casse une des bases du web, le fait qu'il soit ouvert. Ainsi, on ne pourra que difficilement reprendre le code CSS d'un site qui compresse, et c'est donc un frein à l'innovation. Faut-il donc perdre en ouverture et en respect du web pour gagner en performance ? 

Je propose une solution simple pour répondre à cette problématique, mais qui ne marche que dans le cadre du système que je viens de présenter. Il suffit, au moment de la concaténation des fichiers compressés, d'ajouter un commentaire contenant des liens absolus vers les fichiers originaux. Ainsi, l'internaute qui s'intéresse à notre code pourra accéder aux fichiers CSS originaux, et récupérer, analyser, comprendre ce code. Les performances sont là (au dur prix de trois ou quatre lignes de commentaire), et le web est sauvé. 

J'envisage d'implémenter ceci dans la prochaine version de Minifier. Que pensez-vous de cette solution ? Avez-vous d'autres idées pour résoudre ce problème ?

Minifiers

Bon, je suis bien d'accord, mon plugin Minifier est absolument génial (lol), mais il n'est disponible que pour Atomik Framework. Sachez donc qu'il existe d'autres projets permettant de mettre en place le même genre de comportement sur votre site. Certains sont plus simples, d'autres bien plus complets. Je ne sais pas si ils fonctionnent exactement comme Minifier, je vous invite donc à les étudier avant de les implémenter.

Voici donc une liste de projets de minimisation de vos fichiers CSS ou JS à la volée : 

Je me rend compte que je n'en connais pas beaucoup, donc si vous en avez d'autres, faites m'en part en commentaire ! :)

N'hésitez pas non plus à troller intelligemment sur les avantages et les inconvénients de la compression des fichiers CSS et JS, ainsi que sur les différentes méthodes disponibles. 

Belle fin de journée à tous ! 

Crédits : Photo "Astronomical Clock" par simpologist

Monday, 1 March 2010

Mon tutoriel sur Atomik Framework maintenant sur le Site du Zéro

Hello ! 

Je vous fait un petit billet pour vous dire que je suis vivant (je me concentre en ce moment sur la publication sur ideonimbus plutôt que sur ce blog), et que mon tutoriel sur Atomik Framework a été diffusé sur le Site du Zéro : Atomik Framework : un framework PHP simple et léger

N'hésitez pas à y faire un tour, j'ai apporté quelques modifications intéressantes, notamment sur le système de layout. 

Bonne journée ! 

Wednesday, 20 January 2010

Nouvelle version de Programmateur et débuts de l'API

Bonjour à vous, amis développeurs et autres. 

J'ai l'insigne honneur de vous annoncer aujourd'hui le passage de Programmateur à sa version 2. Au programme de cette nouvelle version : rien. Ou presque. 

Version 2.0 ?

En réalité, ce que j'appelle "version 2" est une ré-écriture du code de Programmateur, pour plusieurs raisons. D'abord, parce que Martin m'a demandé si mon code était libre, souhaitant l'utiliser pour un projet similaire. Ensuite, parce que oui, libérer mon code ne me dérange pas, et me parait même une bonne idée. Mais enfin, et surtout, parce que mon code source était juste ignoble : à la base, j'ai développé Programmateur pour m'amuser avec l'API Twitter, et du coup l'organisation du code n'a pas été ma grande priorité... 

Donc, j'ai récemment repris le code de Programmateur, et je suis passé à une version basée sur le framework Atomik (que vous devez commencer à connaitre maintenant ! ;-) ), le code final étant bien plus propre, l'organisation des fichiers plus logique, et surtout, les possibilités d'évolution sont bien meilleures ! J'en ai également profité pour améliorer grandement les performances du site, avec plusieurs mises en cache importantes qui n'étaient pas faite, et donc moins de requêtes vers le site de Twitter (qui, il faut l'avouer, est parfois lent... ). 

Le code source du site n'est pour l'instant pas disponible, parce qu'il faut encore que je fasse quelques vérifications / arrangements, et puis parce qu'il faut que je prépare tout ça, et que ça prend un peu de temps ! Je vous ferai, de toute façon, un billet sur le sujet le jour où le code sera libéré... 

Et une API, une ! 

Au niveau des fonctionnalités, elles restent les mêmes, et rien n'est ajouté. Sauf, sauf... Les premiers pas de l'API de Programmateur ! En effet, comme tout bon service web, je me dois de mettre à disposition des utilisateurs les données que je collecte. Evidemment, c'était déjà possible par le biais de Twitter (la timeline de @programmateur est publique), mais c'est tout de même mieux si ça vient directement du service lui-même. 

Pour l'instant, vous ne pouvez qu'accéder aux derniers tweets via cette URI : http://programmateur.lqbs.fr/tweets/list. Deux options sont actuellement disponibles : "format" qui permet de choisir le format des données retournées (actuellement, xml par défaut, ou json), et "count" qui permet de définir le nombre de tweets retournés (par défaut, 10, au maximum 100). En attendant que je rédige une doc, je vous laisse analyser les données retournées, je pense avoir mis des noms suffisamment clairs (d'autant que je me suis beaucoup basé sur ceux de l'API de Twitter ! ). 

Ce n'est, je l'espère, qu'un début. Je vais notamment essayer de créer rapidement un moyen de poster un tweet via l'API, mais je pense être confronté à pas mal de problèmes d'identification, principalement parce que toute l'identification du site se fait via Twitter... Il faudrait donc que je fasse identifier la requête par Twitter avant de la considérer comme acceptable ? Si vous avez des pistes sur ces problèmes, je suis preneur ! :)

Et bien sur, à terme, il y a aura une documentation complète sur cette API ! En attendant, si vous avez des questions, ou que vous voulez utiliser cette API, n'hésitez pas à vous manifester ici. 

What else ?

Pour finir, et parce que je surfe sur les modes du web, Programmateur a sa page formspring, sur laquelle vous pouvez poser toutes vos questions. Une sorte de FAQ 2.0 : formspring.me/Programmateur

Merci de votre soutien, et longue vie à Programmateur ! \o/

Friday, 8 January 2010

Mise à jour de Minifier, le plugin qui compresse vos fichiers CSS

Bien le bonjour ! 

Souvenez-vous, il y a quelques temps, je vous présentais Minifier, un plugin pour Atomik Framework qui compresse vos fichiers CSS directement sur votre serveur. Plusieurs avantages à cela : 

  • une seule requête HTTP sur chaque page, quel que soit le nombre de vos fichiers CSS
  • suppression des espaces superflus et des commentaires, donc des fichiers plus légers
  • moins de bande passante utilisée
  • une mise en cache des fichiers compressés, donc pas d'utilisation inutile des ressources

Seul "inconvénient", les utilisateurs reçoivent un fichier compressé et donc relativement illisible. Mais honnêtement, dans le cadre d'un site de taille respective, est-ce vraiment un problème ?

Petit rappel pour les gens qui découvrent : ce plugin s'utilise uniquement avec Atomik Framework, un framework PHP5 léger, gratuit, open source, et que j'apprécie beaucoup. 

Bien. Il se trouve que la première version de plugin ne marchait pas bien du tout, parce que j'utilisais des liens pour régler le problème des urls relatives des fichiers CSS. En gros, je créais dans le dossier assets/css/ un lien vers le fichier compressé, ainsi les url étaient prises en compte depuis le dossier assets/css/ et non depuis le dossier de cache. Mais faire des liens en PHP, c'est pas beau, et surtout ça ne marche que très peu sur les serveurs ! A côté de ça, j'avais aussi quelques problèmes au niveau de la manipulation des adresses des fichiers. 

Ce matin, j'ai eu une illumination en repensant à ces problèmes, et j'ai donc pu facilement résoudre le premier : il suffisait tout simplement de mettre les fichiers compressés dans un dossier situé au même niveau que le dossier contenant les CSS ! Par exemple, dans un dossier assets/css_cache/ ! J'ai donc fait ça, et j'en ai profité pour corriger les problèmes d'adresses et pour ajouter quelques fonctionnalités. Vous avez désormais trop moyens d'ajouter le <link>, comme décrit sur la page officielle du plugin. De plus, j'ai ajouté deux clés de configuration : 'cache/dir' contient l'adresse du dossier contenant les fichiers cachés (par défaut, assets/css_cache/), et 'force_css_link' qui force l'affichage de la balise <link> complète plutôt que le retour de l'url du fichier compressé. Des exemples d'utilisation sont disponibles sur la documentation de Minifier

J'espère que les utilisateurs d'Atomik Framework prendront plaisir à utilliser Minifier, et qu'il leur sera utile pour améliorer les performances de leurs sites ! 

Si vous avez des remarques ou des questions, n'hésitez pas à vous exprimer en commentaire ou en m'envoyant un mail

Quelques liens pour finir : 

Bonne journée !

Tuesday, 17 November 2009

Programmateur : les tweets de la semaine, du 8 au 14 novembre 2009

Salut à tous ! 

Bienvenue dans notre rendez-vous hebdomadaire : les tweets de la semaine de @programmateur ! Aujourd'hui, je vous la fait sans image (c'est long de faire tous les screens à la main, et en ce moment j'ai vraiment pas le temps). La forme est encore à bien définir, et j'aimerais d'ailleurs vos avis à ce propos : préférez-vous des liens avec images, comme les deux billets précédents, ou bien une liste (un peu à l'image des bons plans de la semaine d'Amicalement Web) ? Merci de me faire part de vos réponses en commentaires ! :)

Dimanche 8 Novembre 2009

Nice Quickie CSS3 Tricks with Fallbacks #css #css3 (via @smashingmag) - http://bit.ly/Slx0m Le 08/11/2009 à 15:00:00 par @formeolibre

Lundi 9 Novembre 2009

Synthèse du barcamp PHP Toulousain - http://bit.ly/3eCuiG Le 09/11/2009 à 10:00:00 par @methylbro

[en] Du cache en PHP avec Memcache - http://bit.ly/4ftHHI Le 09/11/2009 à 18:00:00 par @adriangaudebert

Mardi 10 Novembre 2009

[en] 3 new and amazing CSS tricks every web designer must know - http://bit.ly/32KA00 Le 10/11/2009 à 10:00:00 par @adriangaudebert

UwAmp : Nouveau serveur Apache MySQL PHP - http://bit.ly/3c7VFP Le 10/11/2009 à 18:00:00 par @methylbro

Mercredi 11 Novembre 2009

[fr] Ruby & Ruby on Rails VS PHP & Symfony - http://bit.ly/4ESl5t Le 11/11/2009 à 10:00:00 par @adriangaudebert

[en] Build a Simple Password Strength Checker - http://bit.ly/2ATkVP Le 11/11/2009 à 18:00:00 par @adriangaudebert

Jeudi 12 Novembre 2009

[fr] Krumo, une amélioration de print_r et var_dump en PHP - http://bit.ly/2zDF9o Le 12/11/2009 à 10:00:00 par @adriangaudebert

[en] 7 Things I Wish I Had Know About jQuery - http://bit.ly/1umXT6 Le 12/11/2009 à 18:00:00 par @adriangaudebert

Vendredi 13 Novembre 2009

[en] 10 Tips for Writing Better CSS - http://bit.ly/3VWIsM Le 13/11/2009 à 10:00:00 par @adriangaudebert

[fr] Une cheat sheet pour jQuery - http://bit.ly/4dy6yh Le 13/11/2009 à 18:00:00 par @adriangaudebert

Samedi 14 Novembre 2009

[en] Optimizing a php application in 5 minutes - http://bit.ly/1W8xq Hier à 15:00 par @adriangaudebert

A suivre... 

Si cette actualité vous a intéressé, n'hésitez pas à suivre @programmateur sur Twitter ! Et si vous estimez qu'une information devrait apparaitre sur @programmateur, proposez-la en utilisant l'interface du site ou en ajoutant #pgmt à votre tweet. 

Passez une bonne journée ! ;)