WebSocket на C++: real-time приложения от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

WebSocket на C++: real-time приложения от А до Я

В современном мире веб-технологий пользователи ожидают мгновенной реакции от приложений. Традиционный HTTP-протокол, работающий по схеме "запрос-ответ", плохо подходит для задач, требующих постоянного обновления данных: онлайн-чатов, биржевых котировок, многопользовательских игр и систем мониторинга. Именно здесь на помощь приходит WebSocket — протокол, обеспечивающий постоянное двунаправленное соединение между клиентом и сервером.

В этой статье мы разберем, как создавать real-time приложения на C++ с использованием WebSocket. Вы узнаете о библиотеках, архитектуре и напишете свой первый рабочий код.

Что такое WebSocket и зачем он нужен в C++?

WebSocket — это протокол, который устанавливает постоянное TCP-соединение между клиентом и сервером. После рукопожатия (handshake) данные могут передаваться в обе стороны без необходимости повторных HTTP-запросов. Это кардинально снижает задержки и нагрузку на сеть.

C++ — идеальный язык для high-performance real-time систем. Он дает полный контроль над памятью, потоками и сетевыми операциями. В сочетании с WebSocket вы получаете:

  • Минимальную задержку — данные доставляются за миллисекунды.
  • Высокую пропускную способность — тысячи одновременных подключений.
  • Энергоэффективность — низкое потребление ресурсов сервера.

Примеры использования: биржевые терминалы, онлайн-игры (например, шахматы в реальном времени), системы уведомлений, IoT-устройства и даже стриминг данных с датчиков.

Выбор библиотеки: Boost.Beast vs uWebSockets

На C++ есть несколько популярных библиотек для работы с WebSocket. Мы рассмотрим две основные:

Boost.Beast

Это часть экосистемы Boost, написанная на современном C++11/14/17. Beast предоставляет низкоуровневый контроль над WebSocket и HTTP. Он асинхронный, основан на Boost.Asio и идеально подходит для серьезных проектов.

uWebSockets (µWebSockets)

Легковесная и сверхбыстрая библиотека. Написана на C++17, ориентирована на максимальную производительность. Идеальна для микросервисов и простых real-time приложений.

Для этого руководства мы выберем Boost.Beast, так как он более гибкий и лучше документирован для образовательных целей.

Пишем WebSocket сервер на C++ с Boost.Beast

Давайте создадим простой эхо-сервер, который принимает сообщения от клиента и отправляет их обратно. Это база для любого real-time приложения.

Для начала установите Boost.Beast и Asio. В большинстве Linux-дистрибутивов это делается через пакетный менеджер:

sudo apt install libboost-all-dev

Теперь код сервера:

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <iostream>
#include <string>
#include <thread>

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

void do_session(tcp::socket&& socket) {
    try {
        websocket::stream<tcp::socket> ws{std::move(socket)};
        ws.accept();

        for (;;) {
            beast::flat_buffer buffer;
            ws.read(buffer);
            auto msg = beast::buffers_to_string(buffer.data());
            std::cout << "Received: " << msg << std::endl;

            // Эхо-ответ
            ws.text(ws.got_text());
            ws.write(buffer.data());
        }
    } catch (beast::system_error const& se) {
        if (se.code() != websocket::error::closed) {
            std::cerr << "Error: " << se.code().message() << std::endl;
        }
    }
}

int main() {
    try {
        net::io_context ioc{1};
        tcp::acceptor acceptor{ioc, tcp::endpoint(tcp::v4(), 8080)};

        std::cout << "WebSocket server started on ws://localhost:8080" << std::endl;

        for (;;) {
            tcp::socket socket{ioc};
            acceptor.accept(socket);
            std::thread{std::bind(&do_session, std::move(socket))}.detach();
        }
    } catch (std::exception const& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return 0;
}

Объяснение:

  • Мы создаем TCP-акцептор на порту 8080.
  • Для каждого нового соединения запускаем отдельный поток (std::thread).
  • Внутри функции do_session выполняем WebSocket-рукопожатие (ws.accept()).
  • Далее в бесконечном цикле читаем сообщения и отправляем их обратно (эхо).

Скомпилируйте с флагом -lpthread и запустите:

g++ -std=c++17 -O2 -pthread server.cpp -o server
./server

Создаем WebSocket клиент на C++

Теперь напишем клиент, который подключается к нашему серверу и отправляет сообщение.

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <iostream>
#include <string>

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

int main() {
    try {
        net::io_context ioc;
        tcp::resolver resolver{ioc};
        websocket::stream<tcp::socket> ws{ioc};

        auto const results = resolver.resolve("127.0.0.1", "8080");
        net::connect(ws.next_layer(), results.begin(), results.end());

        ws.handshake("127.0.0.1", "/");

        std::string message = "Hello, WebSocket!";
        ws.write(net::buffer(message));

        beast::flat_buffer buffer;
        ws.read(buffer);
        std::cout << "                

Блоги

Рекомендаций по книгам