Введение в WebSocket в C++
После рукопожатия WebSocket держит одно TCP-соединение открытым.
Обе стороны могут слать текстовые кадры в любой момент - без
нового HTTP-запроса на каждую фразу. Для учебных примеров на C++
удобна библиотека ixwebsocket: классы ix::WebSocketServer
и ix::WebSocket из заголовков
ixwebsocket/IXWebSocketServer.h и
ixwebsocket/IXWebSocket.h.
Сервер слушает 127.0.0.1 и порт 18082, клиент
подключается к ws://127.0.0.1:18082, шлет строку на
английском; сервер в обработчике входящего кадра может ответить
тем же текстом. Оба конца часто живут в одном main:
сервер запускают после успешного listen, клиент ждет
ответ через атомарный флаг в setOnMessageCallback,
затем вызывают stop у клиента и сервера:
#include <atomic>
#include <iostream>
#include <ixwebsocket/IXWebSocket.h>
#include <ixwebsocket/IXWebSocketServer.h>
int main() {
std::atomic<bool> link_open{false};
std::atomic<bool> got_reply{false};
ix::WebSocketServer server(18082, "127.0.0.1");
server.setOnClientMessageCallback(
[](std::shared_ptr<ix::ConnectionState>,
ix::WebSocket& peer,
const ix::WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Message) {
peer.send(msg->str);
}
});
auto bound = server.listen();
if (!bound.first) {
std::cerr << bound.second << "\n";
return 1;
}
server.start();
ix::WebSocket client;
client.setUrl("ws://127.0.0.1:18082");
client.setOnMessageCallback(
[&](const ix::WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Open) {
link_open.store(true);
link_open.notify_all();
} else if (msg->type == ix::WebSocketMessageType::Message) {
std::cout << msg->str << "\n";
got_reply.store(true);
got_reply.notify_all();
}
});
client.start();
while (!link_open.load()) {
link_open.wait(false);
}
client.send("hello ws");
while (!got_reply.load()) {
got_reply.wait(false);
}
client.stop();
server.stop();
return 0;
}
В консоли появится строка hello ws - это ответ сервера
на одно отправленное сообщение. Соединение при этом оставалось
открытым между отправкой и приемом, что и отличает WebSocket от
разовых HTTP-запросов.