diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-03-09 14:16:46 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-03-20 23:44:57 +0800 |
| commit | 8ab26f85e474dcdbbb2c2fb94b6a087f71952bf8 (patch) | |
| tree | 752c1129db2d363dfd96dd15d27c34f2e126a4e3 | |
| parent | 938ca89e48c2a01d6aa072f01545fa2da585486c (diff) | |
feat: broadcast message from one client to the rest, making chat actually possible
fix(chatServer, CSessionManager): .join sessionThread properly
cleanup(server): unused header
| -rw-r--r-- | src/chatManager.cpp | 15 | ||||
| -rw-r--r-- | src/chatManager.hpp | 19 | ||||
| -rw-r--r-- | src/chatServer.cpp | 13 | ||||
| -rw-r--r-- | src/chatServer.hpp | 2 | ||||
| -rw-r--r-- | src/server.cpp | 1 | ||||
| -rw-r--r-- | src/session.cpp | 8 | ||||
| -rw-r--r-- | src/sessionManager.cpp | 6 | ||||
| -rw-r--r-- | src/sessionManager.hpp | 8 |
8 files changed, 61 insertions, 11 deletions
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 <memory> +#include <string> +#include <vector> + +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<SMessage> m_vMessages; +}; +inline std::unique_ptr<CChatManager> 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<CServer>(8080); g_pSessionManager = std::make_shared<CSessionManager>(); + g_pChatManager = std::make_unique<CChatManager>(); } - 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 <memory> +#include <thread> class CChatServer { public: @@ -9,6 +10,7 @@ public: private: void initManagers(); void initServer(); + std::jthread m_sessionThread; }; inline std::unique_ptr<CChatServer> 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 <cstring> #include <print> #include <sys/socket.h> 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 <cerrno> #include <cstring> #include <sys/socket.h> -#include <unistd.h> +#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<std::jthread, std::shared_ptr<CSession>> *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<std::jthread, std::shared_ptr<CSession>> *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<std::jthread, std::shared_ptr<CSession>> *session); private: + void broadcastChat(const std::string &msg, const std::string &username) const; std::vector<std::pair<std::jthread, std::shared_ptr<CSession>>> m_vSessions; + friend class CChatManager; }; inline std::shared_ptr<CSessionManager> g_pSessionManager; |
