debian

Debian sur la tablette ICOO D50 lite (A13, 50€): Suite

0

Suite à un précédent article ou je diffusais une image utilisable sur la tablette tactile low-cost ICOO D50 lite (image créée par échange de mail avec Ludovic), j’ai enfin obtenu ma propre tablette et j’ai découvert avec joie qu’elle fonctionnait très bien, avec même le tactile en natif.

Bien entendu, l’interface est *très* difficile à utiliser telle quelle, mais les fonctionnalités de la tablette restent un réel atout par rapport à son prix. Petit bémol, la tablette n’est pas livrée avec un chargeur, il faut donc la brancher à un ordinateur ou à un transfo USB pour la recharger.

Pour plus d’informations n’hésitez pas à consulter le billet précédent.

router

Le WiFi, à quand mieux?

2

Récemment, j’ai fait l’expérience de deux événements dans lesquels nous avons découvert les limites du WiFi.

Premièrement, Robots War, un concours de robotique à l’échelle universitaire, dans lequel nos robots pilotés en Ad Hoc WiFi ont posé de nombreux problèmes de communication. Ces derniers qui marchaient pourtant très bien lors des tests en salle ont alors obtenus des pings atroces, à la limite de l’utilisable. J’ai beaucoup remis en cause la carte que nous utilisions, qui est en réalité peu puissante, mais j’ai finalement réalisé que le WiFi lui même devenait très peu fiable lorsqu’il y avait du monde aux alentours.

Plus tard, lors de la Robocup, compétition robotique regroupant une très large foule de geeks, c’était encore pire, le WiFi était devenu parfaitement inutilisable, et tous les participants paramétraient tous leurs robots via un câble ethernet.

En résumé, le WiFi est une technologie très pratique lorsque l’on est seul chez soit à côté de sa box, mais me semble inutilisable lors de grandes manifestations, surtout lorsqu’il y a bon nombres de geeks avec des smartphone dans les poches et des points d’accès sous le bras.

Je suis d’ailleurs très intéressé par une solution ou bonne pratique pour éviter ce problème. Utiliser un bon-gros-routeur-avec-plein-d’antennes? Passer au 5Ghz? Préférer certains canaux? Changer complètement de techno?

mongoose_64x64@2

Serveur web embarqué

0

Déployer une application web, ça n’est pas forcément ouvrir un site qui va accueillir des milliers de personnes et sera disponible sur internet, c’est aussi profiter d’une interface en client léger, et permettre à tous les périphériques du réseau local (ordinateurs, tablettes, téléphones …) d’accéder à votre application.

Cependant, même si de plus en plus de machines permettent de se trimbaler un système d’exploitation, telles que les Raspberry Pi notamment, déployer un serveur Apache et des scripts PHP « classiques » n’est pas toujours une très bonne idée, pour toutes les raisons de performances que l’on peut imaginer.

C’est pour cela qu’il est intéressant de disposer d’un serveur web léger et capable de s’interfacer facilement avec une application bas niveau, par exemple écrite en C++.

C’est en recherchant cela que je suis tombé sur mongoose, un serveur web embarqué qui tient en tout dans un unique fichier C et très léger. Il a d’ailleurs acquis une certaine popularité sur Github. Sur ma machine, il se compile en moins de 2 secondes et ses performances semblent très acceptables. Il supporte également plusieurs features avancés tels que l’upload de fichier ou les websockets.

Seul hic, le développement avec ce mongoose « brut » n’est pas très élégant, car il faut jongler avec des structures de données et une API en C. L’exemple de traitement des requêtes POST donne un peu mal à la tête.

C’est pour cela que j’ai créé un fork de mongoose afin d’y apporter une API C++ permettant d’utiliser beaucoup plus facilement les fonctionnalités du serveur web.

Exemple

Voici un hello world d’exemple, qui répond aux requêtes sur la page /hello?name=Nom en affichant le nom de l’utilisateur echappé:

#include <stdlib.h>
#include <signal.h>
#include <mongoose/Server.h>
#include <mongoose/WebController.h>

using namespace std;
using namespace Mongoose;

class MyController : public WebController
{
    public:
        void hello(Request &request, StreamResponse &response)
        {
            response << "Hello " << htmlEntities(request.get("name", "... what's your name ?")) << endl;
        }

        void setup()
        {
            addRoute("GET", "/hello", MyController, hello);
        }
};

int main()
{
    MyController myController;
    Server server(8080);
    server.registerController(&myController);

    server.start();

    while (1) {
        sleep(10);
    }
}

Dans cet exemple, un serveur web est créé, et sert par défaut les fichiers statiques du dossier www/ à partir du dossier d’exécution du serveur, sur le port 8080.

De plus, grâce à un système de contrôleur enregistré auprès du serveur, il répondra également aux requêtes GET sur l’URL /hello, en appelant la méthode hello du contrôleur.

La réponse hérite en fait ici de ostringstream, ce qui permet de lui ajouter des données simplement avec l’opérateur « << ».

Comme vous le voyez, accéder aux paramètres GET de la requête est aussi très facile à l’aide de request.get().

Comme on peut le voir dans un autre exemple plus complet, mon API permet également de manipuler des variables de sessions, les variables POST, et aussi de changer les en-têtes de la réponse.

Il est également possible de modifier le type de la réponse utilisée par les routes, et de créer ainsi par exemple un serveur web supportant une API JSON.

Application

Ce système peut permettre d’embarquer facilement un serveur web dans n’importe quelle application « lourde » C++. Et ce indépendamment de toute grosse bibliothèque qui pourrait exister (pour ne pas citer Qt ou boost par exemple).

C’est donc en effet approprié pour une utilisation dans l’embarqué comme par exemple une exécution à bord d’un petit ordinateur tel que la Raspberry Pi ou d’un MK802. Il pourrait être utilisé pour piloter un robot ou un appareil (routeur, télévision, serveur divers…).

Conclusions

Comme je risque de m’en servir dans de futurs projets, je compte continuer de maintenir mongoose-cpp et de merger mongoose de temps en temps pour rester à jour. J’aimerais aussi y ajouter une manière simple d’utiliser les websockets, comme cela est permis par mongoose.

Ce qui est assez remarquable, c’est l’intérêt de cette architecture qui utilise un outil très léger entièrement écrit en C pour y ajouter une fine couche d’ingénieurie logiciel, ce qui fait au final un outil à la fois performant et facile à utiliser. Implémenter un serveur web intégralement en C++ avec un génie logiciel au cordeau aurait sans doute donné une application nettement plus longue à compiler et moins performante.

Liens

Haut de page