summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libsock/server/client.hpp10
-rw-r--r--include/libsock/server/clients.hpp11
-rw-r--r--include/libsock/server/server.hpp9
-rw-r--r--src/server/client.cpp17
-rw-r--r--src/server/clients.cpp27
-rw-r--r--src/server/server.cpp29
6 files changed, 74 insertions, 29 deletions
diff --git a/include/libsock/server/client.hpp b/include/libsock/server/client.hpp
index 1799f34..0579a38 100644
--- a/include/libsock/server/client.hpp
+++ b/include/libsock/server/client.hpp
@@ -1,6 +1,8 @@
#pragma once
#include "../types.hpp"
+#include "clients.hpp"
+#include "server.hpp"
#include <any>
#include <format>
#include <functional>
@@ -12,12 +14,6 @@
namespace LibSock {
namespace Server {
-class Server;
-class Clients;
-
-extern SP<Server> pServer;
-extern SP<Clients> pClients;
-
struct SRecvData {
std::string data;
const size_t size = 1024;
@@ -52,7 +48,7 @@ class Client {
bool isValid();
private:
- Client(SP<Server> server = SP<Server>(pServer), SP<Clients> clients = pClients, bool track = false, bool oneShot = true);
+ Client(SP<Server> server = pServer, SP<Clients> clients = pClients, bool track = false, bool oneShot = true);
WP<Client> self;
SP<LibSock::CFileDescriptor> m_sockfd;
diff --git a/include/libsock/server/clients.hpp b/include/libsock/server/clients.hpp
index ba0b40d..8eccbb7 100644
--- a/include/libsock/server/clients.hpp
+++ b/include/libsock/server/clients.hpp
@@ -3,6 +3,7 @@
#include "../types.hpp"
#include <any>
#include <functional>
+#include <memory>
#include <optional>
#include <string>
#include <thread>
@@ -17,9 +18,10 @@ struct SData {
std::string msg;
std::optional<WP<Client>> sender = std::nullopt;
};
-class Clients {
+
+class Clients : public std::enable_shared_from_this<Clients> {
public:
- Clients();
+ static SP<Clients> create();
~Clients();
WP<Client> newClient(std::optional<std::function<std::any(WP<Client>)>> cb = std::nullopt);
@@ -36,13 +38,16 @@ class Clients {
std::vector<SData> getDatas() const;
private:
+ Clients();
void broadcast(const SData &msg);
std::vector<std::pair<std::jthread, SP<Client>>> m_vClients;
std::vector<SData> m_vDatas;
+ SP<Clients> get();
+
friend class Client;
};
-
+inline SP<Clients> pClients;
} // namespace Server
} // namespace LibSock
diff --git a/include/libsock/server/server.hpp b/include/libsock/server/server.hpp
index 1b52e2f..225bdb0 100644
--- a/include/libsock/server/server.hpp
+++ b/include/libsock/server/server.hpp
@@ -1,24 +1,27 @@
#pragma once
#include "../types.hpp"
+#include <memory>
#include <mutex>
#include <netinet/in.h>
-#include <vector>
namespace LibSock {
namespace Server {
-class Server {
+class Server : public std::enable_shared_from_this<Server> {
public:
- Server(uint16_t port, bool reuseaddr = true, bool keepalive = false);
+ static SP<Server> create(uint16_t port, bool reuseaddr = true, bool keepalive = false);
~Server();
SP<LibSock::CFileDescriptor> getSocket() const;
private:
+ Server(uint16_t port, bool reuseaddr = true, bool keepalive = false);
SP<LibSock::CFileDescriptor> m_sockfd;
sockaddr_in m_addr;
uint16_t m_port;
+ SP<Server> get();
+
mutable std::mutex m_mutex;
};
inline SP<Server> pServer;
diff --git a/src/server/client.cpp b/src/server/client.cpp
index cfc512a..01e4544 100644
--- a/src/server/client.cpp
+++ b/src/server/client.cpp
@@ -16,13 +16,16 @@ using namespace LibSock::Server;
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(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 :/
+ pServer = std::move(server);
+ pClients = std::move(clients);
+
+ if (!pClients)
+ throw std::runtime_error("server:client: ClientManager doesn't exist");
+ if (!pServer)
+ throw std::runtime_error("server:client: Server doesn't exist");
+
+ m_sockfd = std::make_shared<LibSock::CFileDescriptor>(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("server:client: Failed to create socket");
diff --git a/src/server/clients.cpp b/src/server/clients.cpp
index c957d92..201ccc6 100644
--- a/src/server/clients.cpp
+++ b/src/server/clients.cpp
@@ -9,6 +9,9 @@
using namespace LibSock::Server;
+namespace LibSock {
+namespace Server {
+
void Clients::shutdownClients(std::optional<std::function<std::any(const std::vector<std::pair<std::jthread, SP<Client>>> &)>> cb) {
if (m_vClients.empty())
return;
@@ -27,14 +30,25 @@ void Clients::shutdownClients(std::optional<std::function<std::any(const std::ve
Clients::Clients() {
if (std::atexit([]() {
- pClients->shutdownClients();
+ if (pClients)
+ pClients->shutdownClients();
}))
void(); // failed to register exit handler...
+}
+
+SP<Clients> Clients::create() {
if (pClients)
- throw std::runtime_error("server:client: ClientManager already exist");
+ throw std::runtime_error("server:clients ClientManager already exist");
- pClients = SP<Clients>(this);
-};
+ pClients = SP<Clients>(new Clients());
+ return pClients;
+}
+
+SP<Clients> Clients::get() {
+ if (!pClients)
+ pClients = shared_from_this();
+ return pClients;
+}
Clients::~Clients() {
for (auto &[thread, client] : m_vClients) {
@@ -45,7 +59,7 @@ Clients::~Clients() {
}
WP<Client> Clients::newClient(std::optional<std::function<std::any(WP<Client>)>> cb) {
- SP client = SP<Client>(new Client());
+ SP client = SP<Client>(new Client(pServer, shared_from_this()));
auto &instance = m_vClients.emplace_back(std::jthread([client]() { client->run(); }), client);
instance.second->self = std::weak_ptr<Client>(instance.second);
if (cb)
@@ -111,3 +125,6 @@ void Clients::kick(WP<Client> clientWeak, const bool kill, const std::string &re
}
}
}
+
+} // namespace Server
+} // namespace LibSock
diff --git a/src/server/server.cpp b/src/server/server.cpp
index 5f10ac6..63ada20 100644
--- a/src/server/server.cpp
+++ b/src/server/server.cpp
@@ -8,6 +8,9 @@
using namespace LibSock::Server;
+namespace LibSock {
+namespace Server {
+
Server::Server(uint16_t port, bool reuseaddr, bool keepalive)
: m_sockfd(
std::make_shared<LibSock::CFileDescriptor>(socket(AF_INET, SOCK_STREAM, 0))
@@ -36,10 +39,28 @@ Server::Server(uint16_t port, bool reuseaddr, bool keepalive)
if (bind(m_sockfd->get(), reinterpret_cast<sockaddr *>(&m_addr), sizeof(m_addr)) ||
listen(m_sockfd->get(), 5))
throw std::runtime_error("server:server Failed to bind or listen on socket");
+}
+
+SP<Server> Server::create(uint16_t port, bool reuseaddr, bool keepalive) {
+ if (pServer)
+ throw std::runtime_error("server:server Server already exist");
+ pServer = SP<Server>(new Server(port, reuseaddr, keepalive));
+ return pServer;
+}
+
+SP<Server> Server::get() {
+ if (!pServer)
+ pServer = shared_from_this();
+ return pServer;
+}
- pServer = SP<Server>(this);
-};
+Server::~Server() {
+ m_sockfd.reset();
+}
-Server::~Server() { m_sockfd.reset(); }
+SP<LibSock::CFileDescriptor> Server::getSocket() const {
+ return m_sockfd;
+}
-std::shared_ptr<LibSock::CFileDescriptor> Server::getSocket() const { return m_sockfd; }
+} // namespace Server
+} // namespace LibSock