#include "ydi_server.h" #include #include #include #include #include #include #include #include #include namespace ydi::server { struct Service { std::optional context{ std::nullopt }; std::optional socket{ std::nullopt }; std::unordered_set revealedClues{}; std::recursive_mutex mtx{}; std::atomic stop_threads{ false }; std::optional client{ std::nullopt }; }; std::optional service{ std::nullopt }; thread_local std::optional receiveThread{ std::nullopt }; thread_local std::optional pingThread{ std::nullopt }; void receive_thread_entry() { using namespace std::chrono_literals; zmq::multipart_t incoming{}; while (service->stop_threads) { std::this_thread::sleep_for(20ms); std::scoped_lock lock{ service->mtx }; if (incoming.recv(*service->socket)) { } } } void ping_thread_entry() { using namespace std::chrono_literals; { std::scoped_lock lock{ service->mtx }; if (!service->client) { return; } } static zmq::multipart_t ping{ make_multipart(*service->client, std::string("PING")) }; while (!service->stop_threads) { std::this_thread::sleep_for(1s); std::scoped_lock lock{ service->mtx }; ping.send(*service->socket); } } void open() { service.emplace(); try { service->context.emplace(1); } catch (...) { service.reset(); return; } try { service->socket.emplace(*service->context, zmq::socket_type::router); } catch (...) { service->context->close(); service->context.reset(); service.reset(); return; } try { service->socket->connect("tcp://*:6667"); } catch (...) { service->socket->close(); service->socket.reset(); service->context->close(); service->context.reset(); service.reset(); } receiveThread.emplace(receive_thread_entry); } void close() { if (service) { std::scoped_lock lock{ service->mtx }; service->socket->close(); service->socket.reset(); service->context->close(); service->context.reset(); service.reset(); } } }