WebSocket em C++: aplicações em tempo real de nível avançado

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

WebSocket em C++: Criando aplicações real-time de alta performance



No mundo moderno do desenvolvimento web, a interação em tempo real (real-time) tornou-se o padrão de facto para plataformas financeiras, jogos online, sistemas de monitoramento e chats. Se você precisa de máxima performance e latência mínima, C++ continua sendo a escolha sem alternativa. Neste artigo, exploraremos técnicas avançadas de trabalho com WebSocket em C++, indo além de um simples servidor echo.



Vamos nos concentrar em soluções arquiteturais que permitem lidar com dezenas de milhares de conexões simultâneas e analisar exemplos de código específicos usando bibliotecas populares.



1. Escolha da biblioteca e configuração do projeto



Para desenvolvimento em produção com C++, existem duas abordagens principais: usar a biblioteca de alto nível uWebSockets (uWS) ou a combinação de baixo nível Boost.Asio + Boost.Beast. A primeira opção é mais simples, a segunda oferece controle total.



Boost.Beast (baseado em Asio) é o padrão da indústria para projetos onde cada microssegundo importa. Vamos considerar a estrutura básica de um servidor WebSocket assíncrono:



#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 para lidar com uma única conexãoclass 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() { // Aceita o handshake WebSocket de forma assíncrona ws_.async_accept( beast::bind_front_handler(&WebSocketSession::on_accept, shared_from_this())); }

void on_accept(beast::error_code ec) { if(!ec) { // Envia uma mensagem de boas-vindas ws_.async_write( net::buffer(std::string("Bem-vindo ao mundo real-time!")), beast::bind_front_handler(&WebSocketSession::on_write, shared_from_this())); do_read(); } } // ... (continuação abaixo)};


Ponto-chave: cada cliente recebe sua própria instância de WebSocketSession, operando em modo assíncrono. Isso permite não bloquear a thread principal ao aguardar dados.



2. Arquitetura de servidor multithread com pool de threads



Uma única thread de io_context encontra o limite da CPU. Para escalar para milhares de conexões, use um pool de threads. Cada thread executa sua própria instância de io_context, e as conexões são distribuídas através de balanceamento de accept.



void run_server(const std::string& address, unsigned short port, int thread_count) {    net::io_context ioc{thread_count}; // Cria io_context especificando o número de threads

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

// Inicia o accept em loop std::function<void()> do_accept = [&]() { acceptor.async_accept( [&](beast::error_code ec, tcp::socket socket) { if (!ec) { // Cria uma sessão e passa o socket para ela std::make_shared<WebSocketSession>(std::move(socket))->run(); } do_accept(); // Continua aceitando }); }; do_accept();

// Inicia o 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();}


Importante

Blogs

Book Recommendations