From 8ab26f85e474dcdbbb2c2fb94b6a087f71952bf8 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Sun, 9 Mar 2025 14:16:46 +0800 Subject: feat: broadcast message from one client to the rest, making chat actually possible fix(chatServer, CSessionManager): .join sessionThread properly cleanup(server): unused header --- src/chatManager.cpp | 15 +++++++++++++++ src/chatManager.hpp | 19 +++++++++++++++++++ src/chatServer.cpp | 13 +++++++++---- src/chatServer.hpp | 2 ++ src/server.cpp | 1 - src/session.cpp | 8 ++++---- src/sessionManager.cpp | 6 ++++++ src/sessionManager.hpp | 8 ++++++-- 8 files changed, 61 insertions(+), 11 deletions(-) create mode 100644 src/chatManager.cpp create mode 100644 src/chatManager.hpp (limited to 'src') diff --git a/src/chatManager.cpp b/src/chatManager.cpp new file mode 100644 index 0000000..9711841 --- /dev/null +++ b/src/chatManager.cpp @@ -0,0 +1,15 @@ +#include "chatManager.hpp" +#include "sessionManager.hpp" + +CChatManager::~CChatManager() { + m_vMessages.clear(); +} + +void CChatManager::newMessage(const SMessage &msg) { + broadcastMessage(msg); + m_vMessages.push_back(msg); +} + +void CChatManager::broadcastMessage(const SMessage &msg) { + g_pSessionManager->broadcastChat(NFormatter::fmt(eFormatType::NONE, "{}: {}", msg.username, msg.msg), msg.username); +} diff --git a/src/chatManager.hpp b/src/chatManager.hpp new file mode 100644 index 0000000..d56a886 --- /dev/null +++ b/src/chatManager.hpp @@ -0,0 +1,19 @@ +#include +#include +#include + +class CChatManager { +public: + CChatManager() = default; + ~CChatManager(); + struct SMessage { + std::string msg; + std::string username; + }; + void newMessage(const SMessage &msg); + void broadcastMessage(const SMessage &msg); +private: + void broadcastMessage(const std::string &msg, const std::string &username); + std::vector m_vMessages; +}; +inline std::unique_ptr g_pChatManager; diff --git a/src/chatServer.cpp b/src/chatServer.cpp index 06f2021..2f6ddf5 100644 --- a/src/chatServer.cpp +++ b/src/chatServer.cpp @@ -1,6 +1,7 @@ #include "chatServer.hpp" #include "server.hpp" #include "sessionManager.hpp" +#include "chatManager.hpp" CChatServer::CChatServer() = default; @@ -9,22 +10,26 @@ CChatServer::~CChatServer() { } void CChatServer::cleanup() { - g_pServer.reset(); + g_pChatManager.reset(); g_pSessionManager.reset(); + g_pServer.reset(); + + if (m_sessionThread.joinable()) + m_sessionThread.join(); } void CChatServer::initManagers() { g_pServer = std::make_unique(8080); g_pSessionManager = std::make_shared(); + g_pChatManager = std::make_unique(); } - void CChatServer::start() { initManagers(); // will await while waiting for accept() to return a new client - std::jthread sessionThread = std::jthread(&CSessionManager::enterLoop, g_pSessionManager); - sessionThread.detach(); + m_sessionThread = std::jthread(&CSessionManager::enterLoop, g_pSessionManager); + m_sessionThread.detach(); while (true) { } diff --git a/src/chatServer.hpp b/src/chatServer.hpp index 7109593..e205eb1 100644 --- a/src/chatServer.hpp +++ b/src/chatServer.hpp @@ -1,4 +1,5 @@ #include +#include class CChatServer { public: @@ -9,6 +10,7 @@ public: private: void initManagers(); void initServer(); + std::jthread m_sessionThread; }; inline std::unique_ptr g_pChatServer; diff --git a/src/server.cpp b/src/server.cpp index ac4506f..cfe13c5 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1,5 +1,4 @@ #include "server.hpp" -#include "sessionManager.hpp" #include #include #include diff --git a/src/session.cpp b/src/session.cpp index 06f129e..428b439 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include "chatManager.hpp" CSession::CSession(Hyprutils::OS::CFileDescriptor sockfd) : m_sockfd(std::move(sockfd)) { @@ -47,7 +47,7 @@ void CSession::onSend(const std::string &msg) { void CSession::recvManager() { while (true) { SRecvData recvData = read(); - g_pSessionManager->broadcast(recvData.data, eFormatType::CHAT); + g_pChatManager->newMessage({.msg=recvData.data, .username=m_name}); if (!recvData.good) break; } @@ -91,8 +91,8 @@ bool CSession::registerSession() { write("Name cannot be empty", eFormatType::ERR); registerSession(); } - - m_name = recvData.data; + *std::remove(recvData.data, recvData.data+strlen(recvData.data), '\n') = '\0'; + this->m_name = recvData.data; log(LOG, "Client registered as: {}", m_name); diff --git a/src/sessionManager.cpp b/src/sessionManager.cpp index e449567..84c3709 100644 --- a/src/sessionManager.cpp +++ b/src/sessionManager.cpp @@ -29,6 +29,12 @@ void CSessionManager::broadcast(const std::string &msg, eFormatType type) const session->write(msg, type); } +void CSessionManager::broadcastChat(const std::string &msg, const std::string &username) const { + for (const auto &[thread, session] : m_vSessions) + if (session->getName() != username) + session->write(msg, NONE); +} + void CSessionManager::removeSession(std::pair> *session) { auto it = std::ranges::find_if(m_vSessions, [session](const auto &s) { return s.second.get() == session->second.get(); }); diff --git a/src/sessionManager.hpp b/src/sessionManager.hpp index eb881a7..ea5fce9 100644 --- a/src/sessionManager.hpp +++ b/src/sessionManager.hpp @@ -10,14 +10,18 @@ class CSessionManager { public: CSessionManager(); ~CSessionManager(); - void enterLoop(); + std::pair> *newSession(Hyprutils::OS::CFileDescriptor sockfd); - void broadcast(const std::string &message, eFormatType type = NONE) const; + + void enterLoop(); + void broadcast(const std::string &msg, eFormatType type = NONE) const; void kick(const CSession *session) const; void addSession(const CSession &session); void removeSession(std::pair> *session); private: + void broadcastChat(const std::string &msg, const std::string &username) const; std::vector>> m_vSessions; + friend class CChatManager; }; inline std::shared_ptr g_pSessionManager; -- cgit v1.2.3