Skip to content

Latest commit

 

History

History
163 lines (100 loc) · 9.05 KB

File metadata and controls

163 lines (100 loc) · 9.05 KB

🔝 Retour au Sommaire

22.4.3 — Quand choisir Asio standalone vs Boost.Asio

Section 22.4 : Librairies réseau modernes


Introduction

Standalone Asio et Boost.Asio partagent le même code, le même auteur et la même architecture. Pourtant, le choix entre les deux a des conséquences concrètes sur votre projet : taille des dépendances, fonctionnalités disponibles, temps de compilation, intégration avec l'existant. Cette section vous donne les critères objectifs pour trancher.


Le point fondamental : ce sont les mêmes moteurs

Avant toute comparaison, il faut intérioriser ce fait : au niveau du transport réseau (TCP, UDP, timers, résolution DNS, coroutines, strands), il n'y a aucune différence fonctionnelle ni de performance. Les deux compilent vers le même code machine, utilisent le même backend système (epoll sur Linux), et exposent la même API à un alias de namespace près.

Le choix ne porte donc pas sur « lequel est meilleur pour le réseau » — ils sont identiques — mais sur ce dont vous avez besoin autour du réseau.


Matrice de décision

Critère Standalone Asio Boost.Asio
HTTP/WebSocket natif Non — librairie tierce nécessaire Oui — Boost.Beast
TLS/SSL Possible (wrapper OpenSSL inclus) Même wrapper, mieux documenté dans l'écosystème Boost
JSON intégré Non — nlohmann/json ou autre Boost.JSON disponible
Parsing d'URL Non Boost.URL disponible
Dépendances Zéro (header-only) Boost entier ou sous-ensemble (~100+ headers transitifs)
Temps de compilation Plus rapide Plus lent (headers Boost volumineux)
Taille du binaire Minimale Légèrement plus grande
Installation Simple (un seul dépôt) Plus lourde (Boost complet ou sélection manuelle)
Projet existant avec Boost Dépendance supplémentaire inutile Coût marginal nul
Projet existant sans Boost S'intègre sans friction Introduit une dépendance majeure
Support std::error_code Natif Via boost::system::error_code (compatible)
Documentation Bonne, site officiel Excellente, plus d'exemples communautaires
Communauté / Stack Overflow Moins de résultats Davantage de ressources historiques

Arbre de décision simplifié

Répondez aux questions dans l'ordre — la première réponse « oui » tranche :

1. Avez-vous besoin de HTTP ou WebSocket dans votre code C++ ?
Oui : Boost.Asio + Beast. C'est la seule librairie HTTP intégrée à Asio. Les alternatives (cpp-httplib, cpr) ne s'intègrent pas dans la boucle événementielle Asio.

2. Votre projet utilise-t-il déjà Boost ?
Oui : Boost.Asio. Ajouter une dépendance standalone quand Boost est déjà présent crée de la confusion (deux versions d'Asio cohabitent) et des conflits potentiels de symboles.

3. Avez-vous une contrainte stricte sur les dépendances (embedded, binaire minimal, politique d'entreprise) ?
Oui : Standalone Asio. Zéro dépendance, un seul dépôt Git, intégration triviale.

4. Aucune des conditions ci-dessus ?
Standalone Asio. C'est le choix par défaut pour les nouveaux projets qui n'ont pas besoin de l'écosystème Boost. Moins de dépendances = moins de complexité.


Scénarios concrets

Outil CLI qui communique avec une API REST

Vous construisez un outil en ligne de commande qui interroge une API HTTP et affiche les résultats. Les requêtes sont synchrones (une à la fois, dans l'ordre).

Choix : ni l'un ni l'autre. Pour un client HTTP simple sans boucle événementielle, cpr ou cpp-httplib (section 22.5) sont plus adaptés. Asio est surdimensionné pour des requêtes HTTP synchrones séquentielles.

Agent de monitoring envoyant des métriques via TCP

Vous construisez un démon qui collecte des métriques système et les envoie à un collecteur (Prometheus pushgateway, InfluxDB) via TCP ou UDP, avec des timers périodiques.

Choix : Standalone Asio. Vous avez besoin de sockets TCP/UDP, de timers, et d'une boucle événementielle. Pas de HTTP, pas de WebSocket. Standalone Asio couvre parfaitement le besoin sans dépendance superflue.

Microservice HTTP avec API REST

Vous construisez un service exposant une API REST JSON, déployé dans un conteneur Docker, communiquant avec d'autres services.

Choix : Boost.Asio + Beast + JSON. Vous avez besoin de HTTP, probablement de TLS, et de sérialisation JSON. Beast fournit tout cela dans un écosystème cohérent.

Serveur de jeu multijoueur

Vous construisez un serveur de jeu gérant des milliers de connexions TCP persistantes avec un protocole binaire custom.

Choix : Standalone Asio. Le protocole est custom (pas HTTP), les données sont binaires (pas JSON). Vous avez besoin de performances réseau pures et d'une boucle événementielle avec timers. Standalone Asio est le choix optimal — pas de dépendance inutile, contrôle total sur le protocole.

Proxy / Gateway HTTPS

Vous construisez un reverse proxy qui accepte des connexions HTTPS, inspecte les headers, et forward vers des backends.

Choix : Boost.Asio + Beast. Vous avez besoin de parser du HTTP, de gérer du TLS des deux côtés (client et serveur), et de manipuler des headers. Beast est conçu exactement pour ce cas d'usage.

Librairie réseau réutilisable

Vous construisez une librairie que d'autres projets consommeront.

Choix : Standalone Asio, sauf si la librairie a spécifiquement besoin de Beast. Imposer Boost comme dépendance transitive à vos utilisateurs est un frein à l'adoption. Standalone Asio est une dépendance beaucoup plus légère.


Impact sur les temps de compilation

La différence de temps de compilation est réelle et mesurable, surtout sur les projets de taille moyenne où le coût des headers domine :

Projet type : serveur TCP echo avec coroutines  
Compilateur : GCC 15, -std=c++20 -O2  
Machine : 8 cœurs, NVMe  

                        Compilation    Headers
                        (clean build)  parsés
────────────────────    ─────────────  ────────
Standalone Asio         ~3s            ~400  
Boost.Asio (seul)       ~5s            ~900  
Boost.Asio + Beast      ~8s            ~1500  
Boost.Asio + Beast      ~12s           ~2200  
  + JSON + SSL

Ces chiffres sont indicatifs et varient selon la machine et le projet. Mais la tendance est claire : chaque couche Boost ajoute des headers transitifs. Sur un projet avec des dizaines de fichiers source incluant Beast, l'impact cumulé est significatif.

Atténuations :

  • Precompiled headers (PCH) — Mettez <boost/asio.hpp> et <boost/beast.hpp> dans un PCH. Le coût de parsing n'est payé qu'une fois.
  • ccache (section 2.3) — Le cache de compilation absorbe le coût après le premier build.
  • Modules C++20 — Quand le support des modules sera mature pour Boost (pas encore le cas en 2026 de manière fiable), l'avantage des headers standalone disparaîtra largement.

Stratégie de migration

De Standalone vers Boost

Si votre projet a démarré avec Standalone Asio et que vous avez maintenant besoin de Beast :

  1. Remplacez #include <asio.hpp> par #include <boost/asio.hpp> (ou utilisez le header de compatibilité vu en section 22.4.2).
  2. Remplacez le namespace asio:: par boost::asio:: (un rechercher-remplacer global, ou un alias namespace net = boost::asio;).
  3. Remplacez std::error_code par boost::system::error_code si nécessaire (les versions récentes de Boost acceptent les deux).
  4. Ajoutez find_package(Boost REQUIRED COMPONENTS system) dans CMake.

La migration est mécanique et sans risque — le code réseau ne change pas structurellement.

De Boost vers Standalone

Le chemin inverse (retirer Boost) est tout aussi mécanique, à condition de ne pas utiliser Beast, JSON, URL ou d'autres librairies Boost-only. Si vous les utilisez, la migration implique de les remplacer par des alternatives (cpp-httplib pour HTTP, nlohmann/json pour JSON, etc.), ce qui est un effort plus conséquent.


Résumé

Le choix entre Standalone Asio et Boost.Asio se résume à une question pragmatique : avez-vous besoin de ce que Boost ajoute ?

  • Besoin de HTTP, WebSocket, TLS bien intégré → Boost.Asio + Beast.
  • Boost déjà dans le projet → Boost.Asio par cohérence.
  • Tout autre cas → Standalone Asio, pour sa légèreté.

Ne sur-architecturez pas le choix. Les deux sont excellents, la migration de l'un vers l'autre est triviale, et le code réseau que vous écrirez sera identique dans les deux cas. Choisissez celui qui correspond à vos besoins aujourd'hui — vous pourrez changer demain sans réécriture.


Prochaine étape → Section 22.5 : Clients HTTP — cpr et cpp-httplib, pour les cas où Asio/Beast est surdimensionné et où vous avez simplement besoin de faire des requêtes HTTP.

⏭️ Clients HTTP : cpr (wrapper curl), cpp-httplib