#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::queue messageQueue; std::mutex messageQueueMutex; std::chrono::steady_clock::time_point connectionTime; // Zeitpunkt der Verbindungsherstellung std::chrono::steady_clock::time_point lastPingTime; std::chrono::steady_clock::time_point lastPongTime; int pingTimeoutCount = 0; static constexpr int MAX_PING_TIMEOUTS = 5; // Mehr Versuche bevor Trennung static constexpr int PING_INTERVAL_SECONDS = 30; static constexpr int PONG_TIMEOUT_SECONDS = 60; // Längeres Timeout (Browser können länger brauchen) }; 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); bool isMainAdmin(const std::string &hashedUserId); nlohmann::json getActiveConnections(); void sendMessageToConnection(struct lws *wsi, const std::string &message); void sendMessageToConnection(struct lws *wsi, WebSocketUserData *ud, const std::string &message); void addConnection(const std::string &userId, struct lws *wsi); void removeConnection(const std::string &userId, struct lws *wsi); void removeConnectionByWsi(struct lws *wsi); // Entfernt Verbindung aus allen Einträgen (Fallback) 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 allConnections; // Alle aktiven Verbindungen (auch ohne userId) std::vector workers; static struct lws_protocols protocols[]; static WebSocketServer* instance; };