WebSocket библиотека C++: полный обзор и примеры использования
WebSocket — это протокол полнодуплексной связи поверх TCP, который обеспечивает постоянное соединение между клиентом и сервером. В отличие от HTTP, WebSocket позволяет отправлять сообщения в обе стороны без постоянных повторных запросов, что идеально подходит для чатов, онлайн-игр, биржевых котировок и других real-time приложений.
В C++ есть несколько зрелых библиотек для работы с WebSocket. В этой статье мы рассмотрим три наиболее популярных варианта: Boost.Beast, uWebSockets и libwebsockets. Разберём их особенности, установку и приведём рабочие примеры кода.
1. Boost.Beast — мощный и стандартизированный
Boost.Beast — это библиотека на основе Boost.Asio, которая реализует протоколы HTTP и WebSocket. Она входит в состав Boost (начиная с версии 1.66) и является де-факто стандартом для серьёзных C++ проектов.
Установка
# Установка Boost (Ubuntu/Debian)
sudo apt install libboost-all-dev
# Или сборка из исходников с опцией --with-beast
Пример WebSocket сервера (эхо-сервер)
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.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::acceptor acceptor(ioc, tcp::endpoint(tcp::v4(), 8080));
while (true) {
tcp::socket socket{ioc};
acceptor.accept(socket);
websocket::stream<tcp::socket> ws{std::move(socket)};
ws.accept();
for (;;) {
beast::flat_buffer buffer;
ws.read(buffer);
std::string msg = beast::buffers_to_string(buffer.data());
std::cout << "Получено: " << msg << std::endl;
ws.text(ws.got_text());
ws.write(buffer.data());
}
}
} catch (const std::exception& e) {
std::cerr << "Ошибка: " << e.what() << std::endl;
}
return 0;
}
Пример WebSocket клиента
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/connect.hpp>
#include <iostream>
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("localhost", "8080");
net::connect(ws.next_layer(), results.begin(), results.end());
ws.handshake("localhost", "/");
ws.write(net::buffer(std::string("Привет, сервер!")));
beast::flat_buffer buffer;
ws.read(buffer);
std::cout << "Ответ: " << beast::buffers_to_string(buffer.data()) << std::endl;
ws.close(websocket::close_code::normal);
} catch (const std::exception& e) {
std::cerr << "Ошибка: " << e.what() << std::endl;
}
return 0;
}
2. uWebSockets — быстрый и лёгкий
uWebSockets (µWebSockets) — это высокопроизводительная библиотека, написанная на C++11. Она использует собственный event loop и поддерживает как HTTP, так и WebSocket. Отличается минимальным потреблением памяти и высокой скоростью работы.
Установка
git clone https://github.com/uNetworking/uWebSockets.git
cd uWebSockets
make
sudo make install
Пример эхо-сервера
#include <uwebsockets/App.h>
int main() {
uWS::App().ws<int>("/*", {
.open = [](auto* ws) {
std::cout << "Клиент подключился" << std::endl;
},
.message = [](auto* ws, std::string_view message, uWS::OpCode opCode) {
ws->send(message, opCode); // Отправляем обратно
},
.close = [](auto* ws, int code, std::string_view message) {
std::cout << "Клиент отключился" << std::endl;
}
}).listen(8080, [](auto* listenSocket) {
if (listenSocket) {
std::cout << "Сервер запущен на порту 8080" <