WebSocket библиотеки для C++: полное руководство
WebSocket — это протокол, обеспечивающий полнодуплексную связь между клиентом и сервером поверх одного TCP-соединения. В отличие от HTTP, WebSocket позволяет серверу отправлять данные клиенту без предварительного запроса, что делает его идеальным для чатов, игр, биржевых котировок и других real-time приложений. В экосистеме C++ существует несколько зрелых библиотек, реализующих этот протокол. В этой статье мы рассмотрим три наиболее популярные: Boost.Beast, uWebSockets и libwebsockets.
1. Boost.Beast (рекомендуемый)
Boost.Beast — это библиотека на основе Boost.Asio, предоставляющая HTTP и WebSocket протоколы. Она является частью официального дистрибутива Boost (начиная с версии 1.66). Главные преимущества: строгая типизация, полная поддержка стандарта RFC 6455, интеграция с Asio для асинхронной работы.
Основные возможности:
- Синхронные и асинхронные WebSocket клиенты/серверы
- Поддержка фреймов, пингов/понгов, закрытия соединения
- Работа поверх TLS (через Boost.Asio SSL)
- Кроссплатформенность (Linux, Windows, macOS)
Пример WebSocket сервера (асинхронный):
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
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::v4(), 8080}};
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 EXIT_SUCCESS;
}
2. uWebSockets (uWS)
uWebSockets — это высокопроизводительная библиотека, ориентированная на максимальную скорость и минимальное потребление памяти. Она написана на C++17 и использует собственный event loop (не Boost.Asio). Отлично подходит для микросервисов и приложений с тысячами одновременных подключений.
Ключевые особенности:
- Очень низкая задержка (~2-3 микросекунды на сообщение)
- Поддержка WebSocket, HTTP и SSE (Server-Sent Events)
- Встроенная поддержка TLS (через OpenSSL или BoringSSL)
- Не требует внешних зависимостей (кроме OpenSSL для TLS)
Пример простого WebSocket сервера:
#include "App.h"
int main() {
uWS::App().ws<int>("/*", {
.open = [](auto* ws) {
std::cout << "Client connected" << std::endl;
ws->send("Welcome!", uWS::OpCode::TEXT);
},
.message = [](auto* ws, std::string_view message, uWS::OpCode opCode) {
std::cout << "Received: " << message << std::endl;
ws->send(message, opCode); // эхо
},
.close = [](auto* ws, int code, std::string_view message) {
std::cout << "Client disconnected" << std::endl;
}
}).listen(9001, [](auto* listenSocket) {
if (listenSocket) {
std::cout << "Listening on port 9001" << std::endl;
}
}).run();
return 0;
}