Рассылка по WebSocket в C++
Рассылка на сервере ixwebsocket - обход набора открытых клиентов и отправка одного текста каждому.
Метод getClients у ix::WebSocketServer
возвращает копию множества ix::WebSocket; по нему
проходят циклом и вызывают send с одной и той же
строкой. Так доставляют уведомление всем, кто уже
подключился к 127.0.0.1 на порту 18082.
Один клиент в примере достаточен: после рукопожатия сервер
обходит клиентов и шлет news; единственный участник
получает кадр в setOnMessageCallback:
#include <atomic>
#include <iostream>
#include <ixwebsocket/IXWebSocket.h>
#include <ixwebsocket/IXWebSocketServer.h>
int main() {
std::atomic<bool> link_open{false};
std::atomic<bool> got_news{false};
ix::WebSocketServer server(18082, "127.0.0.1");
server.setOnClientMessageCallback(
[&server](std::shared_ptr<ix::ConnectionState>,
ix::WebSocket&,
const ix::WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Message
&& msg->str == "ready") {
for (const auto& peer : server.getClients()) {
if (peer) {
peer->send("news");
}
}
}
});
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_news.store(true);
got_news.notify_all();
}
});
client.start();
while (!link_open.load()) {
link_open.wait(false);
}
client.send("ready");
while (!got_news.load()) {
got_news.wait(false);
}
client.stop();
server.stop();
return 0;
}
Текст рассылки может быть любым на английском. Главное -
дождаться подключения клиента, затем один раз пройти по
getClients и отправить строку:
#include <atomic>
#include <iostream>
#include <ixwebsocket/IXWebSocket.h>
#include <ixwebsocket/IXWebSocketServer.h>
int main() {
std::atomic<bool> link_open{false};
std::atomic<bool> got_news{false};
ix::WebSocketServer server(18082, "127.0.0.1");
server.setOnClientMessageCallback(
[&server](std::shared_ptr<ix::ConnectionState>,
ix::WebSocket&,
const ix::WebSocketMessagePtr& msg) {
if (msg->type == ix::WebSocketMessageType::Message
&& msg->str == "go") {
for (const auto& peer : server.getClients()) {
if (peer) {
peer->send("alert");
}
}
}
});
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_news.store(true);
got_news.notify_all();
}
});
client.start();
while (!link_open.load()) {
link_open.wait(false);
}
client.send("go");
while (!got_news.load()) {
got_news.wait(false);
}
client.stop();
server.stop();
return 0;
}
Подключите клиента к 127.0.0.1 и доставьте ему
строку "sync" одним обходом getClients
на сервере.
Разошлите "ready" всем клиентам в множестве
сервера. В консоли каждого подключенного должна
появиться эта строка.