Files
yourpart3/src/websocket_server.h
Torsten Schulz (local) 0c36c4a4e5 Refactor WebSocket server message handling to include user data
- Update sendMessageToConnection to accept user data, enhancing message delivery accuracy.
- Improve error handling in WebSocket callbacks by adding user data checks to prevent null pointer exceptions.
- Enhance logging for error responses to provide clearer insights into message handling issues.
2026-01-14 14:38:43 +01:00

90 lines
3.0 KiB
C++

#pragma once
#include <libwebsockets.h>
#include "connection_guard.h"
#include "connection_pool.h"
#include "message_broker.h"
#include <nlohmann/json.hpp>
#include <string>
#include <atomic>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <queue>
#include <condition_variable>
#include <unordered_map>
#include <vector>
#include <memory>
#include <chrono>
struct WebSocketUserData {
std::string userId;
bool pongReceived = true;
std::queue<std::string> 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<std::unique_ptr<Worker>> &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<bool> 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<std::string> messageQueue;
std::shared_mutex connectionsMutex;
std::unordered_map<std::string, std::vector<struct lws*>> connections;
std::vector<struct lws*> allConnections; // Alle aktiven Verbindungen (auch ohne userId)
std::vector<Worker*> workers;
static struct lws_protocols protocols[];
static WebSocketServer* instance;
};