#pragma once #include #include "connection_guard.h" #include "connection_pool.h" #include "message_broker.h" #include #include #include #include #include #include #include #include #include #include #include #include struct WebSocketUserData { std::string userId; bool pongReceived = true; std::string pendingMessage; std::chrono::steady_clock::time_point lastPingTime; std::chrono::steady_clock::time_point lastPongTime; int pingTimeoutCount = 0; static constexpr int MAX_PING_TIMEOUTS = 3; static constexpr int PING_INTERVAL_SECONDS = 30; static constexpr int PONG_TIMEOUT_SECONDS = 10; }; class Worker; // forward class WebSocketServer { public: WebSocketServer(int port, ConnectionPool &pool, MessageBroker &broker, bool useSSL = false, const std::string& certPath = "", const std::string& keyPath = ""); ~WebSocketServer(); void run(); void stop(); void setWorkers(const std::vector> &workerList); private: void startServer(); void processMessageQueue(); void pingClients(); void handleBrokerMessage(const std::string &message); std::string getUserIdFromFalukantUserId(int falukantUserId); void addConnection(const std::string &userId, struct lws *wsi); void removeConnection(const std::string &userId); static int wsCallback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); int port; ConnectionPool &pool; MessageBroker &broker; bool useSSL; std::string certPath; std::string keyPath; std::atomic running{false}; struct lws_context *context = nullptr; std::thread serverThread; std::thread messageThread; std::thread pingThread; std::mutex queueMutex; std::condition_variable queueCV; std::queue messageQueue; std::shared_mutex connectionsMutex; std::unordered_map connections; std::vector workers; static struct lws_protocols protocols[]; static WebSocketServer* instance; };