feat: working on the client-server connection
This commit is contained in:
parent
dc1aed487e
commit
13f9e8479c
11 changed files with 114 additions and 101 deletions
|
|
@ -2,39 +2,48 @@
|
|||
#include "ydi_networking.h"
|
||||
#include <core/os/time.h>
|
||||
#include <core/templates/vector.h>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <stop_token>
|
||||
#include <chrono>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
#include <zmq.hpp>
|
||||
#include <zmq_addon.hpp>
|
||||
|
||||
namespace ydi::server {
|
||||
struct Event {
|
||||
MessageType type;
|
||||
union {
|
||||
ClueID clue;
|
||||
};
|
||||
};
|
||||
struct Service {
|
||||
std::optional<zmq::context_t> context{ std::nullopt };
|
||||
std::optional<zmq::socket_t> socket{ std::nullopt };
|
||||
std::unordered_set<ClueID> revealedClues{};
|
||||
std::unordered_set<ClueID> revealed_clues{};
|
||||
std::recursive_mutex mtx{};
|
||||
std::optional<std::string> client{ std::nullopt };
|
||||
std::queue<Event> unhandled_events{};
|
||||
double lastHeart{ 0.0 };
|
||||
double lastBeat{ 0.0 };
|
||||
|
||||
std::atomic<bool> stop_threads{ false };
|
||||
};
|
||||
|
||||
std::optional<std::thread> receive_thread{ std::nullopt };
|
||||
std::optional<std::thread> ping_thread{ std::nullopt };
|
||||
std::optional<Service> service{ std::nullopt };
|
||||
std::optional<std::thread> receiveThread{ std::nullopt };
|
||||
std::optional<std::thread> pingThread{ std::nullopt };
|
||||
|
||||
void handle_reveal_clue(zmq::multipart_t const &message) {
|
||||
Event evt{ .type = REVEAL, .clue = to_clue_id(message.at(2)) };
|
||||
service->unhandled_events.push(evt);
|
||||
}
|
||||
|
||||
void handle_authorised_message(std::string_view const &sender, std::string_view const &type, zmq::multipart_t &message) {
|
||||
if (type == "BEAT") {
|
||||
void handle_authorised_message(std::string_view const &sender, MessageType type, zmq::multipart_t &message) {
|
||||
if (type == BEAT) {
|
||||
service->lastBeat = Time::get_singleton()->get_unix_time_from_system();
|
||||
} else if(type == "REVEAL") {
|
||||
} else if (type == REVEAL) {
|
||||
handle_reveal_clue(message);
|
||||
} else {
|
||||
multipart(sender, "NOK", "UNKOWN_COMMAND", message).send(*service->socket);
|
||||
|
|
@ -43,18 +52,19 @@ void handle_authorised_message(std::string_view const &sender, std::string_view
|
|||
|
||||
void handle_message(zmq::multipart_t &message) {
|
||||
std::string_view const sender{ message.at(0).to_string_view() };
|
||||
std::string_view const type{ message.at(1).to_string_view() };
|
||||
MessageType type{ to_message_type(message.at(1)) };
|
||||
std::scoped_lock lock{ service->mtx };
|
||||
if (service->client) {
|
||||
if (sender != service->client) {
|
||||
multipart(sender,"NOK", "UNAUTHORIZED_REQUEST").send(*service->socket);
|
||||
if (sender == service->client) {
|
||||
handle_authorised_message(sender, type, message);
|
||||
} else {
|
||||
multipart(sender, "NOK", "UNAUTHORIZED_REQUEST").send(*service->socket);
|
||||
}
|
||||
handle_authorised_message(sender, type, message);
|
||||
} else if (type == "CONNECT") {
|
||||
} else if (type == CONNECT) {
|
||||
service->client.emplace(sender);
|
||||
multipart(sender, "OK", message).send(*service->socket);
|
||||
multipart(sender, OK, message).send(*service->socket);
|
||||
} else {
|
||||
multipart(sender,"NOK", "UNAUTHORIZED_REQUEST", message).send(*service->socket);
|
||||
multipart(sender, NOK, "UNAUTHORIZED_REQUEST", message).send(*service->socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +82,8 @@ void receive_thread_entry() {
|
|||
|
||||
void ping_thread_entry() {
|
||||
using namespace std::chrono_literals;
|
||||
{ std::scoped_lock lock{ service->mtx };
|
||||
{
|
||||
std::scoped_lock lock{ service->mtx };
|
||||
if (!service->client) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -87,45 +98,67 @@ void ping_thread_entry() {
|
|||
}
|
||||
|
||||
void open() {
|
||||
print_line("Server: Starting");
|
||||
service.emplace();
|
||||
try {
|
||||
service->context.emplace(1);
|
||||
} catch (...) {
|
||||
service.reset();
|
||||
print_line("Server: Failed to create context");
|
||||
return;
|
||||
}
|
||||
print_line("Server: Created zmq context");
|
||||
try {
|
||||
service->socket.emplace(*service->context, zmq::socket_type::router);
|
||||
} catch (...) {
|
||||
service->context->close();
|
||||
service->context.reset();
|
||||
service.reset();
|
||||
print_line("Server: Failed to create socket");
|
||||
return;
|
||||
}
|
||||
print_line("Server: Created socket");
|
||||
try {
|
||||
service->socket->connect("tcp://*:6667");
|
||||
service->socket->bind("tcp://*:6667");
|
||||
} catch (...) {
|
||||
service->socket->close();
|
||||
service->socket.reset();
|
||||
service->context->close();
|
||||
service->context.reset();
|
||||
service.reset();
|
||||
print_line("Server: Failed to bind socket");
|
||||
return;
|
||||
}
|
||||
receiveThread.emplace(receive_thread_entry);
|
||||
print_line("Server: Bound socket");
|
||||
receive_thread.emplace(receive_thread_entry);
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (service) {
|
||||
print_line("Server: Shutting down...");
|
||||
std::scoped_lock lock{ service->mtx };
|
||||
service->stop_threads = true;
|
||||
print_line("Server: Stopping Threads...");
|
||||
if (receive_thread && receive_thread->joinable()) {
|
||||
receive_thread->join();
|
||||
}
|
||||
print_line("Server: Receive thread stopped");
|
||||
if (ping_thread && ping_thread->joinable()) {
|
||||
ping_thread->join();
|
||||
}
|
||||
print_line("Server: Ping thread stopped");
|
||||
if (service->socket) {
|
||||
service->socket->close();
|
||||
service->socket.reset();
|
||||
}
|
||||
print_line("Server: Socket closed");
|
||||
if (service->context) {
|
||||
service->context->close();
|
||||
service->context.reset();
|
||||
}
|
||||
print_line("Server: Context closed");
|
||||
service.reset();
|
||||
print_line("Server: Shutdown complete!");
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace ydi::server
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue