Füge Unterstützung für die Verwaltung von WebSocket-Verbindungen hinzu. Implementiere Methoden zum Hinzufügen und Entfernen von Verbindungen basierend auf Benutzer-IDs. Aktualisiere die WebSocket-Callback-Logik, um empfangene Nachrichten zu verarbeiten und Benutzer-IDs zu setzen. Verbessere die Ausgabe von Debug-Informationen zur Nachverfolgung von Verbindungen und Nachrichten.

This commit is contained in:
Torsten Schulz (local)
2025-09-04 10:49:33 +02:00
committed by Torsten (PC)
parent c9dc891481
commit e7a8dc86eb
2 changed files with 71 additions and 6 deletions

View File

@@ -18,12 +18,18 @@ struct lws_protocols WebSocketServer::protocols[] = {
{ nullptr, nullptr, 0, 0 }
};
// Static instance pointer
WebSocketServer* WebSocketServer::instance = nullptr;
WebSocketServer::WebSocketServer(int port, ConnectionPool &pool, MessageBroker &broker,
bool useSSL, const std::string& certPath, const std::string& keyPath)
: port(port), pool(pool), broker(broker), useSSL(useSSL), certPath(certPath), keyPath(keyPath) {}
: port(port), pool(pool), broker(broker), useSSL(useSSL), certPath(certPath), keyPath(keyPath) {
instance = this;
}
WebSocketServer::~WebSocketServer() {
stop();
instance = nullptr;
}
void WebSocketServer::run() {
@@ -108,24 +114,55 @@ void WebSocketServer::pingClients() {
int WebSocketServer::wsCallback(struct lws *wsi,
enum lws_callback_reasons reason,
void *user, void *in, size_t len) {
if (!instance) return 0;
auto *ud = reinterpret_cast<WebSocketUserData*>(user);
switch (reason) {
case LWS_CALLBACK_ESTABLISHED:
ud->pongReceived = true;
std::cout << "WebSocket-Verbindung hergestellt" << std::endl;
break;
case LWS_CALLBACK_RECEIVE: {
std::string msg(reinterpret_cast<char*>(in), len);
// Here you would dispatch the received message to handleBrokerMessage or handleWebSocketMessage
std::cout << "WebSocket-Nachricht empfangen: " << msg << std::endl;
try {
json parsed = json::parse(msg);
if (parsed.contains("event") && parsed["event"] == "setUserId") {
if (parsed.contains("data") && parsed["data"].contains("userId")) {
ud->userId = parsed["data"]["userId"];
std::cout << "User-ID gesetzt: " << ud->userId << std::endl;
// Verbindung in der Map speichern
instance->addConnection(ud->userId, wsi);
}
}
} catch (const std::exception &e) {
std::cerr << "Fehler beim Parsen der WebSocket-Nachricht: " << e.what() << std::endl;
}
break;
}
case LWS_CALLBACK_SERVER_WRITEABLE: {
unsigned char buf[LWS_PRE + 4];
memcpy(buf + LWS_PRE, "ping", 4);
lws_write(wsi, buf + LWS_PRE, 4, LWS_WRITE_TEXT);
// Prüfe ob es eine Nachricht zum Senden gibt
if (ud->pendingMessage.empty()) {
// Ping senden
unsigned char buf[LWS_PRE + 4];
memcpy(buf + LWS_PRE, "ping", 4);
lws_write(wsi, buf + LWS_PRE, 4, LWS_WRITE_TEXT);
} else {
// Nachricht senden
unsigned char buf[LWS_PRE + ud->pendingMessage.length()];
memcpy(buf + LWS_PRE, ud->pendingMessage.c_str(), ud->pendingMessage.length());
lws_write(wsi, buf + LWS_PRE, ud->pendingMessage.length(), LWS_WRITE_TEXT);
ud->pendingMessage.clear();
}
break;
}
case LWS_CALLBACK_CLOSED:
// Remove closed connection if stored
// Verbindung aus der Map entfernen
if (!ud->userId.empty()) {
instance->removeConnection(ud->userId);
}
break;
default:
break;
@@ -139,10 +176,22 @@ void WebSocketServer::handleBrokerMessage(const std::string &message) {
if (parsed.contains("user_id")) {
int fid = parsed["user_id"].get<int>();
auto userId = getUserIdFromFalukantUserId(fid);
std::cout << "Broker-Nachricht für Falukant-User " << fid << " -> User-ID " << userId << std::endl;
std::shared_lock<std::shared_mutex> lock(connectionsMutex);
auto it = connections.find(userId);
if (it != connections.end()) {
std::cout << "Sende Nachricht an User " << userId << ": " << message << std::endl;
// Nachricht in der UserData speichern
auto *ud = reinterpret_cast<WebSocketUserData*>(lws_wsi_user(it->second));
if (ud) {
ud->pendingMessage = message;
}
lws_callback_on_writable(it->second);
} else {
std::cout << "Keine aktive Verbindung für User " << userId << " gefunden" << std::endl;
}
}
} catch (const std::exception &e) {
@@ -171,3 +220,15 @@ void WebSocketServer::setWorkers(const std::vector<std::unique_ptr<Worker>> &wor
workers.push_back(wptr.get());
}
}
void WebSocketServer::addConnection(const std::string &userId, struct lws *wsi) {
std::unique_lock<std::shared_mutex> lock(connectionsMutex);
connections[userId] = wsi;
std::cout << "Verbindung für User " << userId << " gespeichert" << std::endl;
}
void WebSocketServer::removeConnection(const std::string &userId) {
std::unique_lock<std::shared_mutex> lock(connectionsMutex);
connections.erase(userId);
std::cout << "Verbindung für User " << userId << " entfernt" << std::endl;
}