목록Game Dev/Game Server (78)
KoreanFoodie's Study
[C++ 게임 서버] 7-5. Procedure Generator 핵심 : 1. Python 을 이용해 Procedures 를 자동 생성해 보자. 우리는 이전에 BindParam/BindCol 을 이용해서 테이블에 접근을 하곤 했다. 이런 부분을 조금 더, 자동화 시키기 위해 ProcedureGenerator 를 만들어 보자. 우리는 XML 로부터, 테이블에 데이터를 추가하거나 조회하는 API 를 자동으로 만들어 줄 것이다. 먼저 XmlDBParser 가 필요하다. 이건 참고용이니, 접은 글에 넣도록 하겠다. 🙂 더보기 XmlDBParser.py import xml.etree.ElementTree as ET class XmlDBParser: def __init__(self): self.tables = {..
[C++ 게임 서버] 7-4. ORM 핵심 : 1. ORM 을 사용하면, DB 를 간편하게 관리할 수 있다. 이번 글에서는 간단한 ORM 을 만들어 보도록 하겠다. 참고로 ORM 이란... 라고 한다. 자세한 설명은 이 블로그를 참고하자. 음.. 일단 DB 모델을 표현하는 DBModel 과, 현재 DBModel 에 맞게 Table 을 구성해 주는 DBSynchronizer 클래스를 만들 것이다. 그런데... 이게 하나하나 설명하기에는 양이 많고, 굳이 암기할 필요는 없기에... 나중에 필요할 때 슬쩍(?) 들춰보는 것으로 하고, 예제 코드만 기록하고 넘어가도록 하겠다. 절대 귀찮아서 때우려고 하는게 아니다. 😅 더보기 DBModel #pragma once #include "Types.h" NAMESPAC..
[C++ 게임 서버] 7-3. XML Parser 핵심 : 1. DB 도 버전 관리가 필요하며, 따라서 테이블과 쿼리는 버전에 맞게 존재해야 한다. 이를 위한 XML Parser 를 만들어 본다. 프로젝트를 진행하다 보면 자연스럽게 버전 관리가 필요하다. 이는 사실 DB 에도 마찬가지인데, 어떤 버전에서는 특정 테이블에 특정 컬럼이 없다던지, 추후 버전에서 테이블이 추가된다던지 하는 경우가 생길 것이다. 따라서 쿼리도 그런 DB 의 변동에 맞게 내용물이 바뀌어야 하는데... 보통 이를 관리해 주는 직군이 DBA 이다(물론 서버 담당자가 하기도 한다). 우리는 앞으로 이런 DB 쿼리를 XML 로 관리한 다음, 실제로 GameServer 에서 쿼리를 날려줄 때 XML Parser 를 이용해 해당 쿼리가 자동..
[C++ 게임 서버] 7-2. DB Bind 핵심 : 1. TMP 를 활용하여 BindParam/BindCol 을 간략화해 보자. 이전에 DBConnection 을 만들면서, BindParam 을 이용해 데이터를 저장하고, BindCol 을 이용해 DB 에서 값을 조회했다. 그런데 사실 이런 함수들은 타입별로 만들어 줘야 한다. 그래서 DBConnection 에 다음 함수들을 추가하고, 기존 BindParam/BindCol 을 private 으로 빼 줬다. public: boolBindParam(int32 paramIndex, bool* value, SQLLEN* index); boolBindParam(int32 paramIndex, float* value, SQLLEN* index); boolBindP..
[C++ 게임 서버] 7-1. DB Connection 핵심 : 1. 실제로 DB 를 연동해 보자. 연결을 위한 DBConnection/DBConnectionPool 을 만들어 보자. 2. 실습에서는 ODBC 서버를 사용할 것이다. 또한 로그는 파일 시스템에 남겨야 추후 버그를 트래킹할 수 있을 것이다. 이제 게임 서버가 마지막 페이즈에 들어섰다. 기존까지는 로직을 구현했다면, 이제 DB 서버를 연결해 보면서 강의를 마무리하겠다. 그런데... 이제 정말 힘들다. 😹 후.. 그리고 사실 DB 연동을 하는 부분은 모든 API 를 다 외울 필요도 없고, 초기에 세팅을 한 번만 해주면 되는 부분이라, 큰 틀에서 원리 정보만 보고 넘어가도록 하겠다. 먼저, DBConnection 에서 여러 동작을 수행하는 DBC..
[C++ 게임 서버] 6-7. JobTimer 핵심 : 1. JobTimer 를 사용하면, Job 의 배분을 일정 주기 이후 실행하도록 균등하게 배분할 수 있다. 2. 세션이 종료될 때 Memory Leak 이 일어나지 않도록 종료 처리를 잘 해주자. 이전에 Job 의 처리를 쓰레드에게 어느 정도 균등하게 분배하기 위해 Tick 과 소유권에 대한 개념을 도입했다. 그런데 각 쓰레드 별로 Tick 을 루프를 돌며 체크하는 일은 엄청난 낭비가 아닐 수 없다. 😅 이 문제를 해결하기 위해, Global 하게 JobTimer 라는 녀석을 도입해 일정 시간 후, Job 을 알아서 처리하도록 만들어 보자. JobTimer.h struct JobData { JobData(weak_ptr owner, JobRef jo..
[C++ 게임 서버] 6-6. JobQueue #5 핵심 : 1. JobQueue 방식을 이용해 쓰레드가 Job 을 처리할 때 발생하는 병목 현상 문제를 해결해 보자. 2. GlobalQueue 와 Tick 의 개념을 활용해, 이전 글에서 언급했던 두 가지 병목 현상을 해결할 수 있다. 3. 서버 로직과 클라 로직은 각각 분리하여 돌아가도록 구현하는 것이 좋다. 다만 이번 글에서는, DoWorkerJob 함수에서 모든 로직을 한꺼번에 처리하도록 구현하였다. 이번 시간에는 저번 글에서 지적했던 병목 현상을 해결하기 위해, GlobalQueue 와 시간 제한을 주는 방식을 도입해 보자. 일단 Job 부분은 달라진 것이 없는데... JobQueue 에서 Execute 를 해주는 로직을 일부 수정할 것이다. 거..
[C++ 게임 서버] 6-5. JobQueue #4 핵심 : 1. JobQueue 를 템플릿 버전으로 만들어 LockQueue 라는 이름으로 바꿔보자. 2. Job 에 대한 처리를 Push 를 하는 쓰레드 중 일부가 실제로 처리하도록 만들 수 있다. 그럼 메인 서버에서 FlushJob 을 하던 부분을 특정 쓰레드가 담당할 것이다. 3. 2번에 대한 처리를 할 때는, 동기화에 대한 부분과 병목 현상에 대한 부분을 모두 고려해야 한다. 이번 시간에는, Job 을 처리하는 부분을 조금 더 고도화시켜볼 것이다. 또한, 이전에는 GameServer 에서 한 녀석이 FlushJob 을 호출하면서 Job 을 꺼내 하나하나 처리했는데, 이 부분을 그냥 Job 을 추가하는 쓰레드 중 하나가 알아서 처리하도록 만들 것이다..
[C++ 게임 서버] 6-4. JobQueue #3 핵심 : 1. 이번 글에서는 JobSerializer 를 이용해, 람다 함수를 SharedPtr 로 만들어 Push 해 줌으로써 좀 더 간편하게 Job 관리하는 방법을 알아보자. 2. 람다와 SharedPtr 를 함께 쓴다고 해서 Memory Leak 이 일어나지는 않는다. 만약 문제가 있다면 람다와 SharedPtr 를 함께 사용해서 문제가 생기는 것이 아니라, 기본적인 설계가 잘못된 것이다. 이번 시간에는 기존에 만들었던 Job 을 좀 더 간편하게 사용할 수 있도록 구조를 약간 수정해 보자. 먼저 Job 을 아래와 같이 ServerCore 에 만들어줄 것이다. /*--------- Job ----------*/ using CallbackType = ..
[C++ 게임 서버] 6-3. JobQueue #2 핵심 : 1. Job 별로 클래스 상속을 무한히 늘려나가기 보다, Functor 와 Tuple 을 이용해 각 Job 을 간편하게 추가해 보자. 2. C++ 17 에서는 std::apply 를, C++ 11 에서는 Template Meta Programming 을 이용해 특정 Functor 에 임의의 갯수의 인자를 넘겨주는 기능을 구현할 수 있다. 저번 시간에는 Job 과 JobQueue 에 대한 개념을 간단하게 소개했다. 그런데, 사실 Job 이 늘어날 때마다 이를 상속해서 클래스를 무한히 늘려나가는 방식은... Job 의 갯수가 늘어난다고 하면 매우 끔찍한 결과를 초래할 수 있다. Job 을 추가하는 과정을 조금 간략화하기 위해, 템플릿을 이용해 각 ..