Ya un Couac, ou la naissance d'une appli web
Par Clochix le mercredi 12 décembre 2007, 10:30 - Technoweb - Lien permanent
Ce blog est en sommeil depuis longtemps, par manque de temps pour m'en occuper. La faute au salariat et à ma plongée pendant quelques mois dans le codage d'une application web, Couac. Aujourd'hui, elle a atteint un niveau qui commence à la rendre utilisable, même si je butte sur une erreur de choix architectural qui risque de lui être fatale. Et comme je n'ai plus guère de temps pour m'en occuper, il est temps que je la rende publique, dans l'espoir qu'elle puisse servir et que d'autres contributions viennent l'améliorer.
Description
Couac est une application web. Une appli web est un programme qui s'exécute directement dans un navigateur, Firefox par exemple, et vous permet d'effectuer des traitements sans installer de logiciel sur votre poste. L'exemple le plus connu d'application web est le webmail, qui vous permet de lire vos messages de n'importe où simplement en vous connectant sur un site web.
Couac est une sorte de webmail, mais pas seulement. Il offre aujourd'hui 3 fonctions : un webmail, un client de messagerie instantanée Jabber (pour papoter en direct) et un client MySQL (pour administrer des bases de données). Couac ne nécessite aucune installation sur le poste client: il suffit de l'installer sur un serveur et vous pourrez l'utiliser depuis n'importe quel ordinateur équipé de Firefox.
Couac ne fonctionne qu'avec Firefox et les navigateurs utilisant les technologies de la fondation Mozilla (par exemple XulRunner). Il exploite certaines caractéristiques propres à ces navigateurs, en particulier:
- une interface riche, avec des arbres, des menus, etc. C'est un peu comme si vous lanciez Thunderbird à l'intérieur de Firefox.
- des possibilités basiques de travail en étant déconnecté. Par exemple, les mails que vous consultez sont stockés localement sur votre ordinateur. Cela accélère la navigation (on ne charge les données depuis le serveur qu'une seule fois) et permet d'effectuer certaines actions même si votre ordinateur est temporairement déconnecté du réseau (vous pouvez par exemple lire les messages que vous avez chargés ou rédiger des réponses qui seront envoyées quand vous vous reconnecterez).
Couac est un logiciel libre, c'est à dire que si vous disposez d'un serveur (un ordinateur accessible depuis le réseau), vous pouvez l'installer dessus et l'utiliser comme bon vous semble. Couac est un logiciel libre, c'est à dire que vous pouvez étudier son fonctionnement et, si vous possédez quelques connaissances en programmation, vous avez la possibilité de modifier ce fonctionnement pour l'adapter à vos besoin, pour l'améliorer... Vous pourrez ensuite librement utiliser et redistribuer votre version modifiée de Couac. Couac est publié sous la licence GPL v2 ou supérieure, de la FSF. Couac se voudrait aussi un logiciel libérateur, c'est à dire qui vous permette de lire vos mails, chatter avec vos amis, etc, dans un environnement que vous contrôlez.
Histoire et motivations
Il y a bien longtemps, presque un an, j'ai commencé à rédiger un billet sur les applications web. Si je me souviens bien, je voulais entre autre parler des possibilités de travail en mode déconnecté, et en particulier du travail effectué autour du framework Dojo avec les librairies storage (abstraction de stockage local) et offline (pour utiliser une application web sans être connecté).
Et puis l'occasion s'est présentée de tester tout ça: je me suis retrouvé quelque temps piégé derrière un Firewall particulièrement sévère, interdisant tout autre protocole que le HTTP. Plus moyen de continuer à papoter sur Jabber. Il existe évidemment de nombreux services en ligne tels meebo permettant d'utiliser des messageries instantanées via le web, mais parano comme je suis je ne pouvais me résoudre à utiliser des services sans réelle garantie sur leur respect de ma vie privée.
Je me suis alors souvenu de la classe class.jabber.php que j'avais déjà utilisée pour faire une petite bookmarklet de notification Jabber. L'inconvénient est que la connexion au serveur est un processus long. Difficile d'envisager de se connecter à intervalles réguliers pour vérifier l'arrivée de nouveaux messages, il faut maintenir une connexion persistante quelque part. C'est alors que je me suis souvenu (bis) de la classe phpsocketdaemon que l'auteur avait justement conçue comme brique de base d'un serveur IRC.
Un peu de tempête de neurone et Couac était né. L'idée est de développer un logiciel client-serveur permettant d'accéder à différents services via une interface web enrichie et explorant certaines technos telles que le stockage local pour une utilisation hors ligne. Certes c'est pas nouveau (je réutilise en partie un webmail écrit en 2004, que de temps perdu), mais c'est moi qui le fait.
Technologies
Interface
Pour l'interface "client", j'ai choisi d'utiliser XUL et le
framework Dojo. J'avais
envisagé une version en HTML pur, mais pas avant 2027. Par contre si Flex se
libère, compte tenu de sa relative proximité avec XUL, un portage de la partie
client pourrait être envisageable. Mon choix s'est porté sur XUL parce que
c'est à ma connaissance le principal standard ouvert en terme d'interfaces
riches[1]. Cela dit, utiliser XUL pour des applis web
n'est pas de tout repos. Pour des raisons de sécurité, certaines
fonctionnalités sont désactivées (en particulier au niveau de la gestion des
arbres), et j'ai passé bien des heures à essayer de faire fonctionner des trucs
avant de me rabattre sur des bidouilles peu esthétiques. Signer l'application
devrait permettre de résoudre certains soucis, mais pour l'instant je n'ai rien
obtenu de convainquant (euh, je ne veux pas dire de mal, Zoule c'est vachement
bien, c'est moi qui n'ai pas assez lu les docs). A terme j'aimerais proposer
une version de Couac sous forme d'extension à Firefox, ce qui devrait également
faire sauter ces limitations. A voir aussi ce que l'arrivée imminente de
Firefox 3 va changer (par exemple la possibilité d'éditer directement une
feuille d'un arbre, miam !).
J'avais fait au départ le choix d'utiliser un framework javascript dans l'espoir d'avoir une appli relativement portable et pour profiter de certaines bibliothèques fournies par Dojo, mais je suis finalement revenu sur ce choix:
- Dojo n'est pas prévu pour travailler avec XUL (il utilise par exemple des document.write, or les documents XUL ne possèdent pas cette méthode. On peut évidement la créer, mais je n'ai pas obtenu de résultat concluants),
- je n'aime guère la syntaxe des fonctions de manipulation du DOM. Elles n'apportent à vrai dire pas grand chose. Habitué à JQuery, Dojo m'a déçu sur ce point
- même s'il y a sans doute des optimisations à faire, et si les librairies ne sont à charger qu'une fois, je trouve Dojo un peu lourd, il ralentit le chargement initial de l'appli, déjà particulièrement lent lorsqu'il s'agit de restaurer les données enregistrées localement.
Actuellement, la partie cliente de Couac est donc codée en Javascript pur, avec utilisation des fonctions natives de Firefox. Cela dit, je pense regarder à nouveau bientôt du côté de librairies js externes, par exemple pour ajouter de la crypto.
Serveur
Un démon tourne sur le serveur et répond aux requêtes des clients. Ces requêtes lui sont transmises par Apache via un script de passerelle. Il conserve en mémoire des objets (les connexions aux serveurs).
J'utilise ces librairies externes:
- phpsocketdaemon constitue la base.
- jabber.class.php pour l'interface avec Jabber (désolé le site est inaccessible depuis quelques temps)
- mes petites mimines pour l'instant et le reste
Fonctionnalités
- l'urgence était de pouvoir utiliser Jabber, et donc un client Jabber très basique fonctionne. Je m'en sers depuis plusieurs mois sans rencontrer trop de problème. Il permet de papoter, ajouter des contacts, rejoindre un salon, et conserver l'historique en local. Il repose sur la classe jabber.class.php, mais il faudra un jour en changer ou la mettre à jour, car je rencontre de plus en plus de problèmes (impossible de m'identifier sur certains serveurs, parasites lorsqu'on discute avec des contacts sous gmail...)
- la deuxième étape était l'ajout d'un client mail, occasion d'utiliser les fonctions de stockage local pour pouvoir consulter ses mails offline. Il offre la plupart des fonctions de base des webmails
- un client MySQL basique permet d'explorer des bases de données et d'exécuter des requêtes.
Remarques
Defective by design
Hélas Couac est pour ainsi dire mort-né à cause d'une limitation de PHP qui rend quasi impossible son utilisation à grande échelle. PHP n'est pas multi-thread, c'est à dire qu'il ne peut faire qu'une seule chose à la fois. Si par exemple une demande de connexion à un serveur ou l'exécution d'une requête SQL prennent beaucoup de temps, toutes les autres requêtes sont bloquées. Acceptable si on est seul à utiliser l'application, mais pas si plusieurs utilisateurs se connectent simultanément au serveur. Quand je me suis lancé dans le développement, j'avais négligé cet aspect, pensant réussir à le contourner à coup de fork, communication inter-processus ou autre. Hélas toutes mes tentatives ont été vaines (les connexions sont des ressources PHP, donc ne sont pas sérialisables et ne peuvent pas être partagées avec d'autres processus). La seule solution que j'ai trouvée pour l'instant est de répartir la charge entre plusieurs démons PHP tournant en parallèle, mais ce n'est vraiment pas satisfaisant. Il faudrait sans doute ré-écrire toute la partie serveur dans un langage multithread.
Portabilité du serveur
Les requêtes des clients sont transmises au serveur via un pont : un script PHP exécuté classiquement par Apache. Le démon écoute sur un port spécifique qu'il utilise pour communiquer avec le script. Ce point risque de poser un soucis de déploiement, je ne suis pas sûr que l'utilisation de ces fonctions soient autorisée chez les hébergements mutualisés. Tout retour d'expérience sera le bienvenu.
Et maintenant ?
Maintenant j'ai besoin d'aide. Pour tester l'application, et en particulier
son installation. Couac est
hébergé par le projet Gna. Vous pouvez récupérer
le projet directement dans le SVN à l'adresse http://svn.gna.org/svn/couac/trunk/
ou une archive dans l'espace de
téléchargement. update du 23 janvier : Gna propose
une archive à jour de la version la plus récente des sources : http://svn.gna.org/daily/couac-snap...
update du 4 janvier : un début de documentation est disponible ici : http://home.gna.org/couac/
Notes
[1] entretemps, Adobe a entrepris de libérer Flex. Au niveau de la philosophie, Flex est très proche de XUL, la principale différence étant que l'application finale est générée en Flash, donc plus portable mais moins libre.
Commentaires
La question d'un non-geek : euh ben pourquoi une application Web doit -elle s'appuyer encore sur un navigateur alors qu'il existe au moins la possibilité de s'en dispenser avec Prism ?
http://labs.mozilla.com/2007/10/pri...
J'ai essayé Couac avec Prism et... ça déconne
C'est dans ma TODO list,
mais ce n'est pas le plus urgent. Car Prism n'est pas vraiment la cible. Prism
permet de transformer une appli web en pseudo appli desktop. Or à la base le
but de Couac est plutôt d'être une appli nomade qui ne nécessite aucune
installation sur le poste client (à condition de disposer de Firefox). Quand je
suis en déplacement, je peux m'y connecter depuis n'importe quel ordinateur
pour lire mes mails et chatter.
Dans la même lignée que Prism, une évolution possible serait de faire une version sous forme d'extension Firefox. Pour l'avoir en permanence dans la barre latérale.
D'accord, nomade tout ça, moi je veux bien.
) est aussi
"contraignant" en termes de nomadisme que celui de Prism (?)
reste que le lancement d'un navigateur (oui, Firefox forcément
"ne nécessite aucune installation sur le poste client (à condition de disposer de Firefox)" hum...
je suis fervent de Firefox depuis longtemps mais si les applications que j'utilise (ex Gmail, Google docs, Zoho writer, ..) n'ont nul besoin du lancement d'un navigateur je préfèrerai la légèreté, non ?
De même, je suis extension addict, mais si je peux faire plus simple, pourquoi devrais-je empiler lancement de FF + lancement de l'extension ?
La loi de l'évolution est celle de la paresse : si un xulrunner ou prism webapp permet de faire en un clic et 4 secondes ce qui demande 3 clics et 20 secondes autrement, je sais quel choix va l'emporter.
---------- autre chose : l'interface n'est que partiellement transformée en entités et tout est en français. Des plans pour tout mettre dans un dossier locale (mais je ne sais pas si techniquement ça marche comme pour une application motorisée par gecko) avec une version en-US pour diffusion ultérieure ?
je me doute que ce n'est pas une priorité pendant le développement, mais plus tôt on y pense et plus facile c'est à réaliser (je peux donner un coup de main sur ce travail un peu spécifique et pas très passionnant pour les codeurs)
Prism, extension : de toute façon, à terme, j'aimerais bien proposer plusieurs choix: appli web dans Firefox, dans Prism, ou extension. Pour l'instant j'ai quelques dysfonctionnements avec Prism, et comme je ne me suis pas vraiment penché sur le debug dans cet environnement (est-ce qu'on peut utiliser des extensions type Firebug ?), je ne les ai pas encore corrigés. Mais ça devrait venir à court terme. Pour ce qui est de la création d'une extension, ça demande plus de travail, donc c'est un objectif à moyen terme.
Traductions : oui je suis paresseux et je ne fais pas l'effort d'utiliser des entités partout. Cela dit, Gecko souffre d'un bogue signalé depuis longtemps : il ne peut charger les DTD que depuis le chrome, donc dans le cas d'une application web, on ne peut pas charger de traductions à la volée :-( ( cf http://wiki.mozilla.org/XUL:Remove_Privilege#Load_external_DTD ). Donc ce n'est pas trivial, mais il faudra bien que je trouve une solution, car effectivement j'aimerais bien que Couac soit traduit. Il faudra aussi que je traduise tous les messages présents dans le javascript et la partie serveur. En tout cas grand merci pour ta proposition d'aide.
ah c'est bien ce que je craignais, c'est plus compliqué que pour une extension.
Voilà par exemple ce que ça donne
http://goofy37.perso.cegetel.net/ex...
pour trois fichiers xul, mais évidemment j'ai bêtement mis une ligne de doctype qui pointe vers une adresse chrome, comme pour les extensions (ça pourra peut-être servir un jour si tu fais une extension ?)
Si tu veux je peux faire la même chose sur d'autres fichiers xul ou js.
Bon, ça devrait le faire
Je pense que je peux modifier les fichiers XUL à la volée sur le serveur pour insérer le contenu des fichiers de DTD. Je code ça ce ouikende, et si ça marche je m'occuperai sérieusement de l'i18n dans la foulée.
ben alors en voilà trois autres.
http://goofy37.perso.cegetel.net/ex...
Pour les chaînes des fichiers *js, je peux les transférer facilement mais c'est le même problème que pour les xul : la formule magique pour l'adresse des variables ne fonctionnne que dans le chrome (?)
Côté serveur je ne vois que des tombereaux de php. Il y a des messages d'interface là-dedans ? si tu les isoles en un fichier distinct on peut aussi traduire avec l'extension phplangeditor
Je n'ai pas bien compris ton soucis avec le multithread absent de PHP. C'est parce que ton appli est un une démon qui tourne en permanence ?
Parce que si ce n'est pas le cas, et c'est là le gros avantage en légèreté de PHP par rapport à d'autres, tu dois pouvoir gérer les accès concurrentiels au niveau d'Apache et non de PHP, non ?
@Nicolas : oui, pour ne pas avoir à me reconnecter aux serveurs mail, jabber, etc, à chaque requête du client, j'utilise un daemon en PHP (oui je sais, quelle idée) qui conserve les connections. Et ce démon ne peut faire qu'une chose à la fois, donc toute opération un peu coûteuse bloque le serveur. Mais c'est en voie de résolution: les dernières versions dans le trunk n'utilisent plus le démon que pour le module jabber. Pour les autres, je laisse Apache s'occuper des connections persistantes, et ça semble marcher plutôt pas mal.
@Clochix : OK, tu me rassures...