feat: server, client 디렉토리 조정 및 client 헤더 파일 추가. 시나리오
혹은 대화형 클라이언트로 수정
This commit is contained in:
parent
b887f15662
commit
1d103d7f16
12 changed files with 281 additions and 112 deletions
100
server/Session.cpp
Normal file
100
server/Session.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#include "Session.h"
|
||||
#include "PacketHandler.h"
|
||||
#include "SessionManager.h"
|
||||
#include <boost/asio/co_spawn.hpp>
|
||||
#include <boost/asio/detached.hpp>
|
||||
|
||||
Session::Session(tcp::socket socket) : socket_(std::move(socket)) {}
|
||||
|
||||
Session::~Session() {
|
||||
// 필요한 경우 정리 작업 수행
|
||||
}
|
||||
|
||||
void Session::SetNickname(const std::string &nickname) { nickname_ = nickname; }
|
||||
const std::string &Session::GetNickname() const { return nickname_; }
|
||||
|
||||
void Session::SetGold(uint64_t gold) { gold_ = gold; }
|
||||
uint64_t Session::GetGold() const { return gold_; }
|
||||
|
||||
void Session::SetSwordLevel(uint32_t level) { swordLevel_ = level; }
|
||||
uint32_t Session::GetSwordLevel() const { return swordLevel_; }
|
||||
|
||||
void Session::Start() { DoReadHeader(); }
|
||||
|
||||
void Session::Send(std::span<const uint8_t> data) {
|
||||
auto self(shared_from_this());
|
||||
boost::asio::post(
|
||||
socket_.get_executor(),
|
||||
[this, self,
|
||||
msg = std::vector<uint8_t>(data.begin(), data.end())]() mutable {
|
||||
bool writeInProgress = !writeQueue_.empty();
|
||||
writeQueue_.push_back(std::move(msg));
|
||||
if (!writeInProgress) {
|
||||
DoWrite();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Session::DoReadHeader() {
|
||||
auto self(shared_from_this());
|
||||
boost::asio::async_read(
|
||||
socket_, boost::asio::buffer(&packetHeader_, sizeof(PacketHeader)),
|
||||
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
// 바디 크기 결정
|
||||
// 안전 확인: 메모리 고갈을 방지하기 위해 최대 패킷 크기 제한
|
||||
if (packetHeader_.size > 1024 * 10) {
|
||||
socket_.close();
|
||||
return;
|
||||
}
|
||||
|
||||
packetBody_.resize(packetHeader_.size);
|
||||
DoReadBody();
|
||||
} else {
|
||||
// 연결 끊김 또는 에러 발생 시 매니저에서 제거
|
||||
SessionManager::GetInstance().Leave(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Session::DoReadBody() {
|
||||
auto self(shared_from_this());
|
||||
boost::asio::async_read(
|
||||
socket_, boost::asio::buffer(packetBody_.data(), packetBody_.size()),
|
||||
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
Packet packet;
|
||||
packet.header = packetHeader_;
|
||||
packet.payload = packetBody_;
|
||||
|
||||
// 패킷 핸들러 코루틴 실행
|
||||
boost::asio::co_spawn(
|
||||
socket_.get_executor(),
|
||||
PacketHandler::HandlePacket(self, std::move(packet)),
|
||||
boost::asio::detached);
|
||||
|
||||
// 계속해서 읽기
|
||||
DoReadHeader();
|
||||
} else {
|
||||
// 에러 발생 시 매니저에서 제거
|
||||
SessionManager::GetInstance().Leave(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Session::DoWrite() {
|
||||
auto self(shared_from_this());
|
||||
boost::asio::async_write(
|
||||
socket_, boost::asio::buffer(writeQueue_.front()),
|
||||
[this, self](boost::system::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
writeQueue_.pop_front();
|
||||
if (!writeQueue_.empty()) {
|
||||
DoWrite();
|
||||
}
|
||||
} else {
|
||||
// 에러 발생 시 매니저에서 제거
|
||||
SessionManager::GetInstance().Leave(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue