From 1af4b6c2e4155841e904c45970144df8744d0a7b Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Thu, 20 Nov 2025 18:08:56 +0100 Subject: [PATCH] Enhance logging and error handling in sendMessageToConnection method - Introduce detailed logging for the message sending process, including checks for user data validity and message queue status. - Implement additional null checks for user data before and after locking the mutex to ensure thread safety. - Ensure proper message copying to maintain validity during queuing, improving overall stability and error visibility. --- src/websocket_server.cpp | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/websocket_server.cpp b/src/websocket_server.cpp index cc459de..5574975 100644 --- a/src/websocket_server.cpp +++ b/src/websocket_server.cpp @@ -845,31 +845,59 @@ void WebSocketServer::sendMessageToConnection(struct lws *wsi, WebSocketUserData return; } + std::cout << "[sendMessageToConnection] Start, wsi=" << wsi << ", ud=" << ud << ", message.length()=" << message.length() << std::endl; + try { - // Prüfe ob wsi noch gültig ist (wenn verfügbar) - // lws_wsi_is_valid ist nicht in allen Versionen verfügbar, daher try-catch + // Prüfe ob ud noch gültig ist, bevor wir den Mutex locken + std::cout << "[sendMessageToConnection] Prüfe ud-Gültigkeit..." << std::endl; + volatile bool test = ud->pongReceived; + (void)test; + std::cout << "[sendMessageToConnection] ud ist gültig" << std::endl; + + // Kopiere die Nachricht, um sicherzustellen, dass sie gültig bleibt + std::string messageCopy = message; + std::cout << "[sendMessageToConnection] Nachricht kopiert: " << messageCopy.length() << " Bytes" << std::endl; bool wasEmpty = false; { + std::cout << "[sendMessageToConnection] Versuche Mutex zu locken..." << std::endl; std::lock_guard lock(ud->messageQueueMutex); + std::cout << "[sendMessageToConnection] Mutex gelockt" << std::endl; + + // Prüfe ob ud noch gültig ist, nachdem wir den Mutex gelockt haben + if (!ud) { + std::cerr << "[sendMessageToConnection] ud wurde während des Lockens ungültig" << std::endl; + return; + } + + std::cout << "[sendMessageToConnection] Prüfe Queue-Größe..." << std::endl; wasEmpty = ud->messageQueue.empty(); - ud->messageQueue.push(message); + std::cout << "[sendMessageToConnection] Queue war leer: " << wasEmpty << std::endl; + + std::cout << "[sendMessageToConnection] Füge Nachricht zur Queue hinzu..." << std::endl; + ud->messageQueue.push(messageCopy); + std::cout << "[sendMessageToConnection] Nachricht zur Queue hinzugefügt, neue Größe: " << ud->messageQueue.size() << std::endl; } // Nur wenn die Queue leer war, den Callback aufrufen // (sonst wird er bereits durch den WRITEABLE-Handler aufgerufen) if (wasEmpty) { + std::cout << "[sendMessageToConnection] Queue war leer, rufe lws_cancel_service auf..." << std::endl; // Verwende lws_cancel_service, um den Service zu benachrichtigen // Das ist sicherer, wenn wir uns in einem Callback befinden // lws_cancel_service triggert einen Service-Loop, der dann LWS_CALLBACK_SERVER_WRITEABLE aufruft if (context) { lws_cancel_service(context); + std::cout << "[sendMessageToConnection] lws_cancel_service aufgerufen" << std::endl; } } + std::cout << "[sendMessageToConnection] Erfolgreich abgeschlossen" << std::endl; } catch (const std::exception &e) { std::cerr << "[sendMessageToConnection] Fehler: " << e.what() << std::endl; } catch (...) { std::cerr << "[sendMessageToConnection] Unbekannter Fehler" << std::endl; + } catch (...) { + std::cerr << "[sendMessageToConnection] Unbekannter Fehler" << std::endl; } }