Füge Unterstützung für die Verwaltung von WebSocket-Verbindungen im ChatRoom und SSLServer hinzu
- Implementiere die Methode `findUserByToken` in `ChatRoom`, um Benutzer anhand ihres Tokens zu finden. - Ergänze die Logik zur Entfernung von WebSocket-Verbindungen im `SSLServer`, wenn ein Benutzer die Verbindung trennt. - Füge die Methode `isWebSocket` in `ChatUser` hinzu, um zu überprüfen, ob ein Benutzer über eine WebSocket-Verbindung verfügt. - Aktualisiere die Verarbeitung von Verbindungsabbrüchen, um sicherzustellen, dass sowohl die ChatRoom- als auch die SSLServer-Verbindungen korrekt verwaltet werden. - Ergänze Debug-Ausgaben zur Nachverfolgbarkeit der WebSocket-Verbindungen und deren Status.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "server.h"
|
||||
#include "ssl_server.h"
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
@@ -375,6 +376,23 @@ namespace Yc
|
||||
{
|
||||
// Spezielle Nachricht für Verbindungsabbrüche
|
||||
addMessage(ChatUser::system, std::string("user_disconnected"), (*it)->name(), (*it)->color());
|
||||
|
||||
// Entferne auch die SSL-Server-Verbindung falls vorhanden
|
||||
if ((*it)->isWebSocket()) {
|
||||
// Finde den Token für diese Verbindung
|
||||
std::string token = (*it)->getToken();
|
||||
if (!token.empty()) {
|
||||
// Entferne die Verbindung aus dem SSL-Server
|
||||
SSLServer* sslServer = SSLServer::getInstance();
|
||||
if (sslServer) {
|
||||
sslServer->removeConnection(token);
|
||||
#ifdef YC_DEBUG
|
||||
std::cout << "[Debug] Removed SSL connection for token: " << token << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_users.erase(it);
|
||||
break;
|
||||
}
|
||||
@@ -519,6 +537,18 @@ namespace Yc
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatUser> ChatRoom::findUserByToken(std::string token)
|
||||
{
|
||||
for (auto &user : _users)
|
||||
{
|
||||
if (user->getToken() == token)
|
||||
{
|
||||
return user;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ChatRoom::_handleDice()
|
||||
{
|
||||
if (((_type & rounds) == rounds))
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace Yc
|
||||
bool accessAllowed(std::string userName, std::string password);
|
||||
bool userIsInRoom(std::string userName);
|
||||
std::shared_ptr<ChatUser> findUserByName(std::string userName);
|
||||
std::shared_ptr<ChatUser> findUserByToken(std::string token);
|
||||
void addUserWhenQueueEmpty(std::shared_ptr<ChatUser> user);
|
||||
bool userToNewRoom(std::shared_ptr<ChatUser> user, std::string newRoom, std::string password);
|
||||
unsigned int flags();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "server.h"
|
||||
#include "lib/tools.h"
|
||||
#include "lib/base.h"
|
||||
#include <libwebsockets.h>
|
||||
#include <json/json.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -385,6 +386,11 @@ namespace Yc
|
||||
return (toValidate.get() == this);
|
||||
}
|
||||
|
||||
bool ChatUser::isWebSocket() const
|
||||
{
|
||||
return _wsi != nullptr;
|
||||
}
|
||||
|
||||
void ChatUser::sendMsg(MsgType type, const char *message, std::string userName, std::string color)
|
||||
{
|
||||
sendMsg(type, std::string(message), userName, color);
|
||||
@@ -453,11 +459,17 @@ namespace Yc
|
||||
heartbeatCounter = 0;
|
||||
|
||||
// Prüfe Verbindung mit MSG_PEEK (nicht-blockierend)
|
||||
// Für WebSocket: Skip heartbeat check da libwebsockets das verwaltet
|
||||
if (_wsi) {
|
||||
// WebSocket-Verbindung prüfen
|
||||
#ifdef YC_DEBUG
|
||||
std::cout << "[Debug] WebSocket user, skipping socket check" << std::endl;
|
||||
std::cout << "[Debug] WebSocket user, checking connection status" << std::endl;
|
||||
#endif
|
||||
|
||||
// Für WebSocket-Verbindungen verwenden wir einen einfacheren Ansatz:
|
||||
// Wir senden einen Ping und prüfen, ob die Verbindung noch aktiv ist
|
||||
// Da libwebsockets die Verbindung verwaltet, können wir nicht direkt prüfen
|
||||
// Stattdessen verlassen wir uns auf die libwebsockets-Callbacks
|
||||
// für die Erkennung von Verbindungsabbrüchen
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Yc
|
||||
std::string getToken() const;
|
||||
bool validateToken(std::string token);
|
||||
bool isUser(std::shared_ptr<ChatUser> toValidate);
|
||||
bool isWebSocket() const;
|
||||
void sendMsg(MsgType type, std::string message, std::string userName, std::string color);
|
||||
void sendMsg(MsgType type, const char *message, std::string userName, std::string color);
|
||||
void sendMsg(MsgType type, Json::Value message, std::string userName, std::string color);
|
||||
|
||||
@@ -196,6 +196,15 @@ int SSLServer::wsCallback(struct lws *wsi, enum lws_callback_reasons reason, voi
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
std::cout << "[YourChat] WebSocket-Verbindung geschlossen" << std::endl;
|
||||
#ifdef YC_DEBUG
|
||||
std::cout << "[Debug] WebSocket connection closed" << std::endl;
|
||||
#endif
|
||||
// Finde den User für diese Verbindung und entferne ihn
|
||||
_instance->handleWebSocketDisconnect(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE: {
|
||||
// Send ping to keep connection alive
|
||||
unsigned char buf[LWS_PRE + 4];
|
||||
@@ -204,9 +213,6 @@ int SSLServer::wsCallback(struct lws *wsi, enum lws_callback_reasons reason, voi
|
||||
break;
|
||||
}
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
// Connection closed - no need to access user data
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -714,6 +720,39 @@ void SSLServer::addConnection(const std::string& token, struct lws *wsi) {
|
||||
std::cout << "[YourChat] Verbindung für Token " << token << " gespeichert" << std::endl;
|
||||
}
|
||||
|
||||
void SSLServer::handleWebSocketDisconnect(struct lws *wsi) {
|
||||
// Finde den User für diese WebSocket-Verbindung
|
||||
std::shared_lock<std::shared_mutex> lock(_connectionsMutex);
|
||||
for (auto it = _connections.begin(); it != _connections.end(); ++it) {
|
||||
if (it->second == wsi) {
|
||||
std::string token = it->first;
|
||||
lock.unlock(); // Unlock before calling removeConnection
|
||||
|
||||
#ifdef YC_DEBUG
|
||||
std::cout << "[Debug] WebSocket disconnect detected for token: " << token << std::endl;
|
||||
#endif
|
||||
|
||||
// Finde den User in den Räumen und entferne ihn
|
||||
for (auto &room: _rooms) {
|
||||
if (room) {
|
||||
auto user = room->findUserByToken(token);
|
||||
if (user) {
|
||||
#ifdef YC_DEBUG
|
||||
std::cout << "[Debug] Removing disconnected user: " << user->name() << std::endl;
|
||||
#endif
|
||||
room->removeUserDisconnected(user);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Entferne die Verbindung
|
||||
removeConnection(token);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SSLServer::removeConnection(const std::string& token) {
|
||||
std::unique_lock<std::shared_mutex> lock(_connectionsMutex);
|
||||
_connections.erase(token);
|
||||
@@ -721,6 +760,10 @@ void SSLServer::removeConnection(const std::string& token) {
|
||||
std::cout << "[YourChat] Verbindung für Token " << token << " entfernt" << std::endl;
|
||||
}
|
||||
|
||||
SSLServer* SSLServer::getInstance() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
std::shared_ptr<ChatUser> SSLServer::getUserByToken(const std::string& token) {
|
||||
std::shared_lock<std::shared_mutex> lock(_connectionsMutex);
|
||||
auto it = _users.find(token);
|
||||
|
||||
@@ -58,12 +58,16 @@ public:
|
||||
// WebSocket callbacks
|
||||
static int wsCallback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
|
||||
// Connection management
|
||||
void removeConnection(const std::string& token);
|
||||
static SSLServer* getInstance();
|
||||
|
||||
private:
|
||||
void startServer();
|
||||
void processMessageQueue();
|
||||
void handleWebSocketMessage(struct lws *wsi, const std::string& message);
|
||||
void handleWebSocketDisconnect(struct lws *wsi);
|
||||
void addConnection(const std::string& token, struct lws *wsi);
|
||||
void removeConnection(const std::string& token);
|
||||
std::shared_ptr<ChatUser> getUserByToken(const std::string& token);
|
||||
|
||||
std::shared_ptr<Config> _config;
|
||||
|
||||
Reference in New Issue
Block a user