일단은 멀티로 접속이 됨..

This commit is contained in:
2025-06-19 02:42:49 +09:00
parent 1b79d946c3
commit fc8217a608
25 changed files with 584 additions and 574 deletions

View File

@@ -9,6 +9,7 @@
#include "utils/log.h"
#include "utils/snowflake.h"
#include "vulkan_engine/asset/object/model.h"
#include "utils/utils.h"
#define LISTENIP "::"
#define LISTENPORT 9010
@@ -16,37 +17,23 @@ std::uint8_t CLIENTID = 0;
std::unordered_map<utils::Snowflake, veng::Model> MODELS;
std::mutex MODELS_MUTEX;
std::vector<std::pair<Network::TCPSocket, double>> CLIENTS;
std::list<std::shared_ptr<Network::Socket>> CLIENTS;
std::mutex CLIENTS_MUTEX;
void recv_fully(Network::IOCP* iocp, Network::TCPSocket& sock,
std::vector<char>& buffer) {
size_t total_received = 0;
size_t expected = buffer.size();
while (total_received < expected) {
if (total_received != 0)
Sleep(100); // 너무 빨리 재시도해서 큐가 채워질 틈이 없는 듯?
if (sock.sock == 0) return;
std::vector<char> temp(expected - total_received);
size_t received = iocp->recv(sock, temp);
std::copy(temp.begin(), temp.begin() + received,
buffer.begin() + total_received);
total_received += received;
}
}
void EchoClient(utils::ThreadPool* tp, Network::IOCP* iocp,
Network::TCPSocket* NewSock, Network::Address NewAddr) {
std::shared_ptr<Network::Socket> NewSock, Network::Address NewAddr) {
if (NewSock->sock == 0) return;
std::vector<char> recv_data(6);
recv_fully(iocp, *NewSock, recv_data);
std::future<std::list<char>> result;
Packet::Header header;
std::vector<char> recv_data;
result = iocp->recv(NewSock, 14);
recv_data = utils::CvtListToVector(result.get());
header.Deserialize(recv_data);
recv_data.resize(header.body_length);
recv_fully(iocp, *NewSock, recv_data);
result = iocp->recv(NewSock, header.body_length);
recv_data = utils::CvtListToVector(result.get());
switch (header.opcode) {
case Packet::Opcode::UPDATEMODEL: {
@@ -68,24 +55,26 @@ void EchoClient(utils::ThreadPool* tp, Network::IOCP* iocp,
}
void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
static auto last_all_updated = glfwGetTime();
static auto last_frame_time_ = glfwGetTime();
static double last_all_updated;
static double last_frame_time_;
auto current_time = glfwGetTime();
bool needs_all_update = false;
if (current_time - last_all_updated >= 100) {
if (current_time - last_all_updated >= .01f) {
needs_all_update = true;
last_all_updated = glfwGetTime();
}
auto delta_time = current_time - last_frame_time_;
last_frame_time_ = current_time;
CLIENTS_MUTEX.lock();
for (auto it = CLIENTS.begin(); it != CLIENTS.end();) {
if (it->first.sock == 0) {
if (*it == nullptr || it->get()->sock == 0) {
it = CLIENTS.erase(it);
} else {
++it;
}
}
CLIENTS_MUTEX.unlock();
for (auto it = MODELS.begin(); it != MODELS.end();) {
auto& model = it->second;
@@ -110,15 +99,17 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
++it;
}
CLIENTS_MUTEX.lock();
for (auto& client : CLIENTS) {
if (client.first.sock == 0) continue;
if (client->sock == 0) continue;
for (auto& model : MODELS) {
if (model.second.name == "camera_lag") continue;
std::vector<char> send_data;
model.second.Update(delta_time + (client.second / 2));
model.second.Update(delta_time);
auto model_serialized = model.second.Serialize();
Packet::Header header;
header.opcode = Packet::Opcode::UPDATEMODEL;
header.timestamp = glfwGetTime();
header.body_length = model_serialized.size();
auto header_serialized = header.Serialize();
send_data.insert(send_data.end(), header_serialized.begin(),
@@ -129,12 +120,13 @@ void ClientRefresher(utils::ThreadPool* tp, Network::IOCP* iocp) {
continue;
}
model.second.needsUpdate = false;
if (client.first.send(send_data.data(), send_data.size(), 0) == -1) {
client.first.sock = 0;
if (iocp->send(client, send_data) == -1) {
client->sock = 0;
}
spdlog::info("updated: {}", model.second.name);
spdlog::debug("server-side updated : [{}:{}]", model.second.name, model.second.ID.snowflake);
}
}
CLIENTS_MUTEX.unlock();
tp->enqueueJob(ClientRefresher, iocp);
}
@@ -154,15 +146,14 @@ int main(int argc, char* argv[]) {
addr.set(AF_INET6, "::", 9010);
Network::Socket* sock;
Network::TCPSocket TCPSock;
TCPSock.init(AF_INET6);
sock = &TCPSock;
if (TCPSock.bind(addr) == INVALID_SOCKET) {
std::shared_ptr<Network::TCPSocket> TCPSock =
std::make_shared<Network::TCPSocket>();
TCPSock->init(AF_INET6);
if (TCPSock->bind(addr) == INVALID_SOCKET) {
spdlog::error("bind()");
std::exit(EXIT_FAILURE);
}
if (TCPSock.listen(SOMAXCONN) == INVALID_SOCKET) {
if (TCPSock->listen(SOMAXCONN) == INVALID_SOCKET) {
spdlog::error("listen()");
std::exit(EXIT_FAILURE);
}
@@ -170,32 +161,31 @@ int main(int argc, char* argv[]) {
tp.enqueueJob(ClientRefresher, &iocp);
while (true) {
Network::TCPSocket NewSock;
Network::Address NewAddr;
NewAddr.length = addr.length;
std::shared_ptr<Network::TCPSocket> NewSock;
Network::Address NewAddr = addr;
spdlog::info("Waiting for connection");
TCPSock.accept(NewSock, NewAddr);
TCPSock->accept(NewSock, NewAddr);
iocp.registerTCPSocket(NewSock, 16 * 1024);
iocp.registerSocket(NewSock);
Packet::Header header;
std::vector<char> packet;
header.opcode = Packet::Opcode::CLIENTID;
header.body_length = 9;
auto packet = header.Serialize();
packet.resize(packet.size() + 9);
header.timestamp = glfwGetTime();
header.body_length = 1;
packet = header.Serialize();
packet.resize(packet.size() + 1);
std::lock_guard lock(CLIENTS_MUTEX);
std::uint8_t client_id = CLIENTS.size() - 1;
::memcpy(packet.data() + 6, &client_id, 1);
std::uint8_t client_id = (std::uint8_t)(CLIENTS.size() - 1);
::memcpy(packet.data() + 14, &client_id, 1);
std::double_t timestamp = glfwGetTime();
::memcpy(packet.data() + 7, &timestamp, 8);
iocp.send(NewSock, packet);
std::vector<char> header_buf(6);
recv_fully(&iocp, NewSock, header_buf);
auto ping = glfwGetTime() - timestamp;
CLIENTS.emplace_back(std::move(NewSock), ping);
tp.enqueueJob(EchoClient, &iocp, &CLIENTS.back().first, NewAddr);
auto ping = glfwGetTime() - header.timestamp;
CLIENTS.push_back(NewSock);
tp.enqueueJob(EchoClient, &iocp, NewSock, NewAddr);
}
}