Windows/Linux/macOS 크로스플랫폼 고성능 네트워크 서버 엔진 연구 프로젝트. IOCP, RIO, epoll, io_uring, kqueue를 추상화한 2계층 비동기 I/O 아키텍처.
구성요소:
Server/ServerEngine/— 핵심 네트워크 라이브러리 (공유 lib)Server/TestServer/— 게임 서버 (클라이언트 연결 처리 + 비동기 DB)Server/DBServer/— DB 서버Client/TestClient/— 크로스플랫폼 테스트 클라이언트ModuleTest/— AsyncIO / DB 저수준 단위 테스트
상세 내용은
Docs/02_Architecture.md참고.
핵심 요약:
- 2계층 구조: 고수준(
INetworkEngine) + 저수준(AsyncIOProvider) - 폴백 체인: Windows(RIO→IOCP), Linux(io_uring→epoll), macOS(kqueue)
- 패킷:
uint16_t size+uint16_t id헤더,#pragma pack(push,1), Little-Endian
| 대상 | 규칙 | 예 |
|---|---|---|
| 클래스/구조체 | PascalCase | SessionManager, ClientSession |
| 함수/메서드 | PascalCase | Initialize(), OnConnected() |
| 로컬 변수 | camelCase | clientVersion, sessionId |
| 멤버 변수 | m + PascalCase |
mSessions, mDBTaskQueue |
| 상수 | UPPER_CASE | MAX_PACKET_SIZE, DEFAULT_PORT |
| 패킷 구조체 | PKT_ + PascalCase |
PKT_PingReq, PKT_SessionConnectReq |
| 인터페이스 | I + PascalCase |
INetworkEngine, IDatabase |
| 타입 별칭 | Ref/Type/Id 접미 | SessionRef, ConnectionId |
| 열거형 원소 | PascalCase | LogLevel::Debug, SessionState::Connected |
모든 중괄호는 새 줄에 단독으로 위치한다.
// ✅ 올바른 예
void Initialize(int id)
{
if (id > 0)
{
mId = id;
}
else
{
Logger::Warn("Invalid id");
}
}
class ClientSession : public Session
{
public:
void OnConnected() override;
};
// ❌ 잘못된 예 (K&R / Egyptian style)
void Initialize(int id) {
if (id > 0) {
mId = id;
}
}적용 범위: 함수, 클래스, 구조체, if/else, for, while, switch, namespace 등 모든 블록.
namespace Network {
namespace Core { ... } // Session, SessionManager
namespace Utils { ... } // Logger, Timer, SafeQueue
namespace TestServer { ... } // ClientSession, ServerSession, DBServerSession, PacketHandler
}영한 병기:
// English: Initialize the session
// 한글: 세션 초기화- 헤더:
#pragma once, 전방 선언, 클래스 선언, 타입 정의 - 소스: 헤더 include, 네임스페이스 블록, 구현
- 비trivial 구현은 반드시 .cpp에 분리
- 네트워크 계층: 예외 최소화,
bool/int반환값 기반 처리 - DB 계층:
DatabaseException(std::exception 파생) 사용 - 로깅:
Logger::Info/Warn/Error/Debug()일관 사용 - Windows 에러:
GetLastError()결과를 로그에 포함
if (!session->Initialize(id, socket))
{
Logger::Error("Session init failed, id: " + std::to_string(id));
return false;
}Core::Session
├── ClientSession — 게임 클라이언트. 암호화 인터페이스(Encrypt/Decrypt) 보유 (현재 no-op)
└── ServerSession — 서버간 통신 공통 베이스. 재연결 콜백 인터페이스.
└── DBServerSession — DB 서버 전용. DBServerPacketHandler 소유.
- 현재 기본 세션 생성 경로는
SessionManager::CreateSession()+SetSessionConfigurator()이다. 실제 세션 객체는SessionPool의Core::Session이며, recv 콜백은 configurator가SetOnRecv()로 주입한다. ClientSession은 코드 트리에 남아 있지만, 현재 기본 실행 경로를 설명하는 기준 문서로는 사용하지 않는다.DBServerSession이 rawCore::Session직접 사용을 대체.- 연결 생명주기(소켓, recv 스레드, ping 스케줄링) 관리는
TestServer가 담당.
- DB 기록 진입점 명시: 현재 접속/종료 DB 기록은
TestServer이벤트 핸들러가DBTaskQueue에 비동기로 enqueue - 스레드 안전:
SafeQueue,std::atomic,std::mutex기반 동기화 - 팩토리 패턴:
CreateNetworkEngine(),CreateAsyncIOProvider()로 런타임 선택 - Graceful Shutdown: 세션 전부 종료 → 큐 드레인 → 스레드 Join 순서 엄수
- 자동 재연결: 서버↔서버, 클라이언트↔서버 연결 끊김 시 재연결 로직 유지
- 재연결 에러 구분:
WSAECONNREFUSED(서버 종료/재기동 중) → 1s 고정 간격; 그 외 → 지수 백오프(최대 30s) - DBTaskQueue 설정과 구현 구분: 현재
TestServer설정은Initialize(1, ...)이지만, 구현 자체는 워커별 독립 큐 +sessionId % workerCount라우팅이다. 문서에서 이를 단일 공유 큐로 설명하지 않는다. - 의존성 주입 우선: 클래스
static멤버 전역 상태 대신 생성자/팩토리 람다 캡처 방식으로 주입. - 이벤트 일관성:
OnDisconnected/FireEvent는 항상mLogicThreadPool.Submit()을 통해 실행 (CloseConnection포함). - 설정 중앙화:
ConfigManager를 통해 모든 설정값 관리. 환경 변수(NETMOD_*)로 런타임 덮어쓰기 가능.
작업 요약을 반영한 이름으로 브랜치를 생성하고 작업한다.
# 형식: <type>/<brief-summary>
git checkout -b feat/reconnect-backoff
git checkout -b fix/rio-notify-crash
git checkout -b refactor/session-manager-cleanup브랜치 타입: feat, fix, refactor, docs, chore, perf
코드 수정 후 반드시 테스트를 먼저 수행한다.
# 빌드 확인 (Debug)
msbuild NetworkModuleTest.sln /p:Configuration=Debug /p:Platform=x64
# 자동 통합 테스트
.\run_test_auto.ps1 -RunSeconds 10
# Graceful shutdown / 크래시 재현 테스트
.\run_crash_repro.ps1빌드가 깨진 상태로 커밋하지 않는다.
# 원격에 브랜치 푸시
git push -u origin <branch-name>
# PR 생성 (gh CLI)
gh pr create --title "<작업 요약>" --base mainPR 머지 전 체크리스트:
- 빌드 성공 (Debug / Release)
- 통합 테스트 통과
- 커밋 메시지 컨벤션 준수
충돌 발생 시 rebase를 우선 시도하고, 충돌 내역을 로그에 기록한다.
# main 최신화 후 rebase
git fetch origin
git rebase origin/main
# 충돌 해결 후
git add <resolved-files>
git rebase --continue
# rebase 불가 시 merge fallback
git merge origin/main충돌이 발생했다면 커밋 메시지에 명시한다:
fix/feat/...: <작업 요약>
- 변경 내용 요약
- Merge conflict resolved: <충돌 파일 또는 원인 간략 기술>
- 언어: C++17 (stdcpplatest)
- 주 개발 환경: Windows, Visual Studio 2026 (MSVC v143)
- 솔루션:
NetworkModuleTest.sln(x64/Debug, x64/Release) - CMake:
Client/TestClient/및ModuleTest/MultiPlatformNetwork/ - 주요 링크 라이브러리:
ServerEngine.lib,WS2_32.lib,odbc32.lib
| 변수 | 설명 | 기본값 |
|---|---|---|
NETMOD_LISTEN_PORT |
서버侦听端口 | 19010 |
NETMOD_DB_HOST |
DB服务器主机 | 127.0.0.1 |
NETMOD_DB_PORT |
DB服务器端口 | 18002 |
NETMOD_ENGINE |
网络引擎 (auto/rio/iocp/epoll/kqueue) | auto |
NETMOD_WORKER_THREADS |
Worker线程数 (0=auto) | 0 |
NETMOD_LOG_LEVEL |
日志级别 (DEBUG/INFO/WARN/ERROR) | INFO |
NETMOD_GRACEFUL_TIMEOUT |
正常关机超时(秒) | 8 |
# Docker 빌드 및 실행
docker compose up -d --build
# Docker 중지
docker compose down# 빠른 자동 테스트 (5초)
.\run_test_auto.ps1 -RunSeconds 5
# 대화형 테스트 (서버 전체 기동)
.\run_allServer.ps1 -ServerPort 19010 -DbPort 18002
# 개별 기동
.\run_dbServer.ps1 -DbPort 18002
.\run_server.ps1 -ServerPort 19010 -DbPort 18002
.\run_client.ps1프로세스 기동 순서: TestDBServer(18002) → TestServer(19010) → TestClient
| 플랫폼 | 상태 | 비고 |
|---|---|---|
| Windows | ✅ 주 개발 | IOCP(안정) / RIO(고성능) 완전 검증 |
| Linux | epoll / io_uring 검증 필요 | |
| macOS | kqueue 검증 필요 |