WebSocket en C++ : applications temps réel de niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

WebSocket en C++ : Création d'applications temps réel haute performance



Dans le monde moderne du développement web, l'interaction temps réel est devenue un standard de facto pour les plateformes financières, les jeux en ligne, les systèmes de surveillance et les chats. Si vous avez besoin d'une performance maximale et d'une latence minimale, C++ reste le choix incontournable. Dans cet article, nous explorerons des techniques avancées de travail avec WebSocket en C++, allant au-delà d'un simple serveur echo.



Nous nous concentrerons sur les solutions architecturales permettant de gérer des dizaines de milliers de connexions simultanées, et analyserons des exemples de code concrets utilisant des bibliothèques populaires.



1. Choix de la bibliothèque et configuration du projet



Pour le développement en production en C++, il existe deux approches principales : l'utilisation de la bibliothèque de haut niveau uWebSockets (uWS) ou la combinaison de bas niveau Boost.Asio + Boost.Beast. La première option est plus simple, la seconde offre un contrôle total.



Boost.Beast (basé sur Asio) est la norme de l'industrie pour les projets où chaque microseconde compte. Examinons la structure de base d'un serveur WebSocket asynchrone :



#include <boost/beast/core.hpp>#include <boost/beast/websocket.hpp>#include <boost/asio.hpp>#include <memory>#include <string>

namespace beast = boost::beast;namespace websocket = beast::websocket;namespace net = boost::asio;using tcp = net::ip::tcp;

// Classe pour gérer une seule connexionclass WebSocketSession : public std::enable_shared_from_this<WebSocketSession> { websocket::stream<beast::tcp_stream> ws_; beast::flat_buffer buffer_;public: explicit WebSocketSession(tcp::socket&& socket) : ws_(std::move(socket)) {}

void run() { // Acceptation asynchrone de la poignée de main WebSocket ws_.async_accept( beast::bind_front_handler(&WebSocketSession::on_accept, shared_from_this())); }

void on_accept(beast::error_code ec) { if(!ec) { // Envoi d'un message de bienvenue ws_.async_write( net::buffer(std::string("Bienvenue dans le monde temps réel !")), beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this())); do_read(); } } // ... (suite ci-dessous)};


Point clé : chaque client reçoit sa propre instance de WebSocketSession, fonctionnant en mode asynchrone. Cela permet de ne pas bloquer le thread principal lors de l'attente de données.



2. Architecture du serveur multithread avec pool de threads



Un seul thread io_context se heurte à la limite du CPU. Pour passer à l'échelle jusqu'à des milliers de connexions, utilisez un pool de threads. Chaque thread exécute sa propre instance de io_context, et les connexions sont réparties via un équilibrage d'acceptation.



void run_server(const std::string& address, unsigned short port, int thread_count) {    net::io_context ioc{thread_count}; // Création de io_context avec le nombre de threads

tcp::acceptor acceptor{ioc, {net::ip::make_address(address), port}};

// Boucle d'acceptation std::function<void()> do_accept = [&]() { acceptor.async_accept( [&](beast::error_code ec, tcp::socket socket) { if (!ec) { // Création d'une session et transmission du socket std::make_shared<WebSocketSession>(std::move(socket))->run(); } do_accept(); // Continuer à accepter }); }; do_accept();

// Lancement du pool de threads std::vector<std::thread> threads; for (int i = 0; i < thread_count; ++i) { threads.emplace_back([&ioc]() { ioc.run(); }); }

for (auto& t : threads) t.join();}


Important

Blogs

Book Recommendations