summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libsock/server/client.hpp28
-rw-r--r--include/libsock/server/server.hpp8
-rw-r--r--src/server/client.cpp36
-rw-r--r--src/server/clients.cpp18
-rw-r--r--src/server/server.cpp14
5 files changed, 55 insertions, 49 deletions
diff --git a/include/libsock/server/client.hpp b/include/libsock/server/client.hpp
index ec5c6bc..eb528a2 100644
--- a/include/libsock/server/client.hpp
+++ b/include/libsock/server/client.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "../types.hpp"
+#include "server.hpp"
#include <format>
#include <functional>
#include <netinet/in.h>
@@ -11,7 +12,7 @@
#include <vector>
namespace LibSock {
-namespace Client {
+namespace Server {
struct SRecvData {
std::string data;
@@ -29,9 +30,12 @@ enum eEventType : std::uint8_t {
WRITE
};
+class Clients;
+inline SP<Clients> pClients;
+
class Client {
public:
- Client(bool track = false, bool oneShot = true);
+ Client(SP<Server> server = SP<Server>(pServer), SP<Clients> clients = pClients, bool track = false, bool oneShot = true);
~Client();
const std::string &getName() const;
@@ -49,15 +53,15 @@ class Client {
bool isValid();
private:
- WP<Client> self;
+ WP<Client> self;
SP<LibSock::CFileDescriptor> m_sockfd;
- sockaddr_in m_addr;
- socklen_t m_addrLen = sizeof(m_addr);
- std::string m_name;
- std::string m_ip;
- int m_port;
- bool m_track;
- bool m_oneShot;
+ sockaddr_in m_addr;
+ socklen_t m_addrLen = sizeof(m_addr);
+ std::string m_name;
+ std::string m_ip;
+ int m_port;
+ bool m_track;
+ bool m_oneShot;
std::optional<std::string> m_szReading = std::nullopt;
@@ -98,7 +102,5 @@ class Clients {
std::vector<std::pair<std::jthread, SP<Client>>> m_vClients;
std::vector<SData> m_vDatas;
};
-inline SP<Clients> pClients;
-
-} // namespace Client
+} // namespace Server
} // namespace LibSock
diff --git a/include/libsock/server/server.hpp b/include/libsock/server/server.hpp
index d831fd8..1b52e2f 100644
--- a/include/libsock/server/server.hpp
+++ b/include/libsock/server/server.hpp
@@ -1,7 +1,9 @@
#pragma once
+
#include "../types.hpp"
#include <mutex>
#include <netinet/in.h>
+#include <vector>
namespace LibSock {
namespace Server {
@@ -14,11 +16,11 @@ class Server {
private:
SP<LibSock::CFileDescriptor> m_sockfd;
- sockaddr_in m_addr;
- uint16_t m_port;
+ sockaddr_in m_addr;
+ uint16_t m_port;
mutable std::mutex m_mutex;
};
-inline UP<Server> pServer;
+inline SP<Server> pServer;
} // namespace Server
} // namespace LibSock
diff --git a/src/server/client.cpp b/src/server/client.cpp
index 9efad18..5de8b79 100644
--- a/src/server/client.cpp
+++ b/src/server/client.cpp
@@ -1,28 +1,30 @@
#include "libsock/server/client.hpp"
+#include "libsock/server/server.hpp"
#include "libsock/types.hpp"
#include "misc/FileDescriptor.hpp"
-// #include "chatManager.hpp"
-#include "libsock/server/server.hpp"
-// #include "sessionManager.hpp"
#include <algorithm>
#include <arpa/inet.h>
-#include <cerrno>
#include <cstring>
#include <format>
+#include <memory>
#include <optional>
#include <sys/socket.h>
-using namespace LibSock::Client;
+using namespace LibSock::Server;
-Client::Client(bool track, bool oneShot) : m_track(track), m_oneShot(oneShot) {
+Client::Client(SP<Server> server, SP<Clients> clients, bool track, bool oneShot)
+ : m_track(track)
+ , m_oneShot(oneShot) {
+ if (!pServer || !pClients)
+ throw std::runtime_error("server:client: Server/ClientManager doesn't exist");
m_sockfd = std::make_shared<LibSock::CFileDescriptor>(
- accept(LibSock::Server::pServer->getSocket()->get(),
- reinterpret_cast<sockaddr *>(&m_addr),
- &m_addrLen)); // if this is in the init list, it will run before
- // m_addrLen, so it won't work :/
+ accept(pServer->getSocket()->get(), reinterpret_cast<sockaddr *>(&m_addr),
+ &m_addrLen)
+ ); // if this is in the init list, it will run before
+ // m_addrLen, so it won't work :/
if (!m_sockfd->isValid())
- throw std::runtime_error("session: Failed to create socket");
+ throw std::runtime_error("server:client: Failed to create socket");
m_ip.resize(INET_ADDRSTRLEN);
inet_ntop(AF_INET, &m_addr.sin_addr, &m_ip[0], INET_ADDRSTRLEN);
@@ -68,7 +70,7 @@ void SRecvData::sanitize() {
if (const auto start = data.find_first_not_of(" \t\r\n");
start != std::string::npos) {
const auto end = data.find_last_not_of(" \t\r\n");
- data = data.substr(start, end - start + 1);
+ data = data.substr(start, end - start + 1);
} else
data.clear();
}
@@ -98,8 +100,7 @@ Client::read(std::optional<std::function<void(const SRecvData &)>> cb) {
}
UP<SRecvData>
-Client::read(const std::string &msg,
- std::optional<std::function<void(const SRecvData &)>> cb) {
+Client::read(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb) {
write("{}", msg);
m_szReading = msg;
return read();
@@ -118,18 +119,17 @@ bool Client::isValid() {
if (!m_sockfd->isValid() || m_name.empty())
return false;
- int err = 0;
+ int err = 0;
socklen_t size = sizeof(err);
return getsockopt(m_sockfd->get(), SOL_SOCKET, SO_ERROR, &err, &size) >=
0 &&
err == 0;
}
-bool Client::write(const std::string &msg,
- std::optional<std::function<void(const SRecvData &)>> cb) {
+bool Client::write(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb) {
const auto r = write("{}", msg);
if (cb) {
- auto recvData = std::make_unique<SRecvData>();
+ auto recvData = std::make_unique<SRecvData>();
recvData->data = msg;
recvData->good = r;
(*cb)(*recvData);
diff --git a/src/server/clients.cpp b/src/server/clients.cpp
index e42579c..5fc63df 100644
--- a/src/server/clients.cpp
+++ b/src/server/clients.cpp
@@ -5,7 +5,7 @@
#include <unistd.h>
#include <utility>
-using namespace LibSock::Client;
+using namespace LibSock::Server;
void Clients::shutdownClients() {
if (m_vClients.empty())
@@ -15,7 +15,7 @@ void Clients::shutdownClients() {
if (client) {
client->write("Server shutting down");
if (!client->getName().empty())
- pClients->broadcast(std::format("{} has left the chat", client->getName()), WP<Client>(client));
+ broadcast(std::format("{} has left the chat", client->getName()), WP<Client>(client));
}
}
@@ -29,11 +29,11 @@ void Clients::shutdownClients() {
}
Clients::Clients() {
- if (std::atexit([]() {
- if (pClients)
- pClients->shutdownClients();
- }))
- void(); // failed to register exit handler...
+ // if (std::atexit([&]() {
+ // shutdownClients();
+ // }))
+ // void(); // failed to register exit handler...
+ pClients = SP<Clients>(this);
};
Clients::~Clients() {
@@ -47,7 +47,7 @@ Clients::~Clients() {
void Clients::newClient(std::optional<std::function<void()>> cb) {
if (cb)
(*cb)();
- SP client = std::make_shared<Client>();
+ SP client = std::make_shared<Client>(pServer, SP<Clients>(this));
auto &instance = m_vClients.emplace_back(std::jthread([client]() { client->run(); }), client);
instance.second->self = std::weak_ptr<Client>(instance.second);
}
@@ -114,7 +114,7 @@ void Clients::kick(WP<Client> clientWeak, const bool kill, const std::string &re
// this only exist when the client is registered
// not sure why the second is null, but m_name definately is since it's setted during register
// but we don't need to notify people if the client didn't even "join"/register anyways
- pClients->broadcast(std::format("{} has left the chat", client->getName()), clientWeak);
+ broadcast(std::format("{} has left the chat", client->getName()), clientWeak);
if (!reason.empty())
client->write(reason);
diff --git a/src/server/server.cpp b/src/server/server.cpp
index 2e07809..e63cd58 100644
--- a/src/server/server.cpp
+++ b/src/server/server.cpp
@@ -9,12 +9,13 @@ using namespace LibSock::Server;
Server::Server(uint16_t port, bool reuseaddr, bool keepalive)
: m_sockfd(
- std::make_shared<LibSock::CFileDescriptor>(socket(AF_INET, SOCK_STREAM, 0))) {
+ std::make_shared<LibSock::CFileDescriptor>(socket(AF_INET, SOCK_STREAM, 0))
+ ) {
std::lock_guard<std::mutex> lk(m_mutex);
if (!m_sockfd->isValid() || m_sockfd->get() < 0)
throw std::runtime_error("Failed to create socket");
- constexpr int opt = 1;
+ constexpr int opt = 1;
constexpr int size = sizeof(opt);
if (keepalive &&
setsockopt(m_sockfd->get(), SOL_SOCKET, SO_REUSEADDR, &opt, size) < 0)
@@ -25,13 +26,14 @@ Server::Server(uint16_t port, bool reuseaddr, bool keepalive)
throw std::runtime_error("setsockopt(SO_KEEPALIVE) failed");
memset(&m_addr, 0, sizeof(m_addr));
- m_addr.sin_family = AF_INET;
- m_addr.sin_port = htons(port);
+ m_addr.sin_family = AF_INET;
+ m_addr.sin_port = htons(port);
m_addr.sin_addr.s_addr = INADDR_ANY;
- if (bind(m_sockfd->get(), reinterpret_cast<sockaddr *>(&m_addr),
- sizeof(m_addr)) ||
+ if (bind(m_sockfd->get(), reinterpret_cast<sockaddr *>(&m_addr), sizeof(m_addr)) ||
listen(m_sockfd->get(), 5))
throw std::runtime_error("Failed to bind or listen on socket");
+
+ pServer = SP<Server>(this);
};
Server::~Server() { m_sockfd.reset(); }