Обмен WebSocket-сообщениями в C++
Полный цикл в одной программе: сервер в фоне принимает строку и отвечает, клиент подключается, шлет запрос и получает кадр в колбэке сообщений.
Главный поток не должен завершиться раньше ответа. Ожидание
удобно связать с std::atomic: флаг сбрасывают в
обработчике входящего текста и ждут через wait.
Печать ответа - обычный std::cout:
#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("pong");
}
});
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("ping");
while (!got_reply.load()) {
got_reply.wait(false);
}
client.stop();
server.stop();
return 0;
}
Тот же каркас подходит для других коротких фраз. Сервер может подставить фиксированный ответ, не зависящий от текста запроса:
#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("done");
}
});
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("start job");
while (!got_reply.load()) {
got_reply.wait(false);
}
client.stop();
server.stop();
return 0;
}
Отправьте "time" и выведите ответ "now" в
консоли клиента.
Обменяйтесь фразами "ask" и "reply" в одном
запуске. На экране должна появиться только строка ответа.