[C++] Serveur web Comet embarqué < 400ko de mémoire

Salut,

Ça commence à se préciser donc je teste un peu la température auprès de mes fadas favoris, à savoir vous… :wink:

En ce moment je bosse (entre autres) sur un serveur web embarqué en C++11 (g++4.7 minimum – Wheezy donc, bien qu’en bricolant le sources.list/preferences ça fonctionne aussi sur Squeeze sans trop de paquets upgradés), basé sur la lib GNU libmicrohttpd, et dont l’empreinte mémoire de base est inférieure à 400ko (380ko aux dernières nouvelles, et encore c’est l’appli complète dont certaines parties sont propriétaires… vu le code je pense que le serveur lui-même atteint les 250-300ko). :open_mouth: Bien sûr en réalité il est censé prendre plus, mais comme le reste c’est des libs partagées avec tout le système, ça “compte pas” dans l’occupation mémoire vu qu’elles sont déjà chargées de toutes façons (genre libc6, libstdc++ etc). Avec une AP wifi sur le serveur embarqué j’ai des temps de réponse < 50ms (CPU ARM @400MHz) donc je pense que c’est pas trop mal, surtout avec une pauvre carte SD comme stockage de masse (10 Mo/s… sérieusement ?) et quasiment pas de RAM pour faire tampon. :mrgreen:

Accessoirement il gère Comet (server-push / long-polling en “quasi” temps réel, autant que faire ce peut en HTTP) ce qui me paraît suffisamment rare pour être mentionné, d’autant que ce type de serveur utilise d’habitude des technos qui sont énormément plus lourdes (des 100aines de Mo au bas mot d’après les produits que j’ai vus – basés sur Java / Node.js et autres trucs inutilisables quand t’as que 32mo de RAM sur ta machine).

Testé sur x86 / amd64 / ARM. Il est capable de servir “out of the box” des fichiers statiques (répertoire “www-root” et sous-répertoires, avec éventuellement fichiers d’index) avec ou sans indications de cache HTTP, le tout en moins de 50 lignes de code client (exemple livré avec). Par contre toute la partie dynamique y compris Comet doit être écrite en C++ – pas de langage de script pour rester svelte. Et évidemment c’est fortement multithread, faut pas avoir peur des mutex et autres condition_variable bien que la plupart des détails soient relativement masqués.

Pour ne rien gâcher, d’où le fait que j’en parle ici, j’ai l’autorisation écrite de ma boîte (après quelques négociations :unamused:) de le publier sous mon nom en LGPL. :041

Prévoir 3 à 6 mois avant d’avoir une version publiable… (faut que je refactorise, commente et documente, mais là tout de suite j’ai d’autres chats à fouetter – saloperies de deadlines inhumaines)
Ça intéresse du monde ? Vous pensez que ça vaut la peine que je nettoie le code et que je publie mon merdier ?

PS: oui forcément je suis fier de ce que j’ai “fait avec mes petites mains”. Mais le but de ce fil c’est surtout d’avoir des réactions “oh oui super on a jamais vu ça” ou au contraire “lol tu sers à rien y’en a 10.000 qui ont fait ça avant toi”… histoire que je sache où me placer quoi. Pas utile que je me fasse chier à maintenir un produit qui a déjà 10.000 concurrents plus pertinents avant même de commencer – oui je suis un gros fainéant – d’où la description technique un peu longue histoire de pouvoir comparer. :wink: Après tout mon Google-foo n’est pas sans faille, loin de là, surtout quand il s’agit d’une niche aussi limitée. :slightly_smiling:

Salut.
J’ai jamais entendu parler comet, google n’est pas ami sur ce coup.

Du coup, logiquement, j’évite toute suggestion :slightly_smiling:

En français (pas terrible) : fr.wikipedia.org/wiki/Server_push
En anglais (beaucoup plus complet) : en.wikipedia.org/wiki/Push_technology
Si tu veux c’est du Websockets avant que les Websockets n’existent (fallait bien se débrouiller :mrgreen: et tant qu’il y a des vieux navigateurs à gérer c’est toujours d’actualité).

Mais Comet n’est qu’un “accessoire” (même si c’est une obligation pour moi dans le cadre de mon boulot), l’intérêt du truc je pense c’est surtout qu’il utilise 3 à 4 fois moins de RAM qu’un Nginx (qui pourtant est renommé pour être léger) au prix d’une diminution des fonctionnalités – mais rien de gênant pour une utilisation basique où on ne sert que des fichiers statiques voire une couche dynamique “simple*” par dessus, et qu’il n’y a pas trop de clients derrière. De l’embarqué léger quoi.

(*) sachant que le total tourne autour de 5 kloc, répartis à peu près moitié-moitié entre le serveur web lui-même (la surcouche libmicrohttpd quoi) et l’appli proprio qui l’utilise (faut encore que je sépare proprement les deux). Autant dire rien du tout. :open_mouth:

On reçoit une information du serveur sans rien démandé.
C’est cool cet chose au nom bizarre :laughing:

Et pour la partie configuration ? C’est “Apache compatible” ? ou un truc a ta sauce ?

Abonnement: Oh, c’est cool super, je n’ai jamais vu ça :049

En fait le serveur web lui-même c’est juste une lib… Dans un sens la configuration est infinie, mais c’est à toi d’écrire le code. :mrgreen:
L’exemple “de base” qui sert uniquement des fichiers statiques a exactement 5 paramètres de configuration :

  • numéro de port
  • timeout keepalive
  • emplacement du répertoire racine
  • autoriser à suivre les symlinks qui emmènent en dehors du répertoire racine ?
  • durée du cache navigateur

Pour le moment il n’y a même pas de mécanisme pour changer d’utilisateur, si tu veux un port < 1024 c’est forcément en root (ce qui n’est pas gênant dans mon cas vu que le filesystem embarqué est en lecture seule, impossible de reflasher la carte à partir de Debian).
Bref, c’est encore très rustique, c’est vraiment prévu pour faire de l’embarqué même si on peut sans peine imaginer d’autres utilisations – à condition de pas avoir besoin d’une pile HTTP très évoluée.

Ok, c’est du serveur Web en kit quoi :mrgreen:

En tous cas bien jouer pour avoir eut l’autorisation de mettre ton code en LGPL. :023

Oui c’est exactement ça, t’as mis le doigt sur la bonne expression. :laughing: