목록Game Dev (263)
KoreanFoodie's Study

[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 을 추가하는 과정을 조금 간략화하기 위해, 템플릿을 이용해 각 ..

[C++ 게임 서버] 6-2. JobQueue #1 핵심 : 1. Command 패턴은, 실행될 동작에 대한 인터페이스를 만들어 구체적인 동작은 해당 인터페이스를 상속 받은 객체에서 결정하도록 하는 설계 기법이다. 2. Command 패턴과 JobQueue 를 이용하면, 이전에 Broadcast 로 인한 동작의 병목 현상(LOCK 으로 인한)을 줄일 수 있다. 이전 시간에 간단한 채팅 서버를 만들어 보았다. 다만 이전 방식은 Broadcast 를 하는 부분에서 병목 현상이 심각할 수 있다는 단점이 있었는데... 이를 해결하기 위해, 우리는 JobQueue 를 만들어 순차적으로 이 문제를 해결해볼 것이다. 일단 이번 시간에는 Command 패턴을 이용해 조악하게나마 JobQueue 를 구축해 보자. Com..

[C++ 게임 서버] 6-1. 채팅 실습 핵심 : 1. Chat 서버를 만들어보자. 간단하게는 채팅이 전파될 Room 과 채팅 패킷만 만들어 주면 된다. 2. 채팅을 전파할 때마다, Room 에서 WRITE_LOCK 을 잡으면 병목현상이 생길 수 있다. 이를 해결하기 위해, 추후 JobQueue 를 도입할 것이다. 이번에는 채팅 패킷을 만들어 보면서, 간단하게 실제로 패킷을 추가하는 작업을 어떻게 진행하는지 살펴볼 것이다. 일단, 우리가 작업했던 Protocol.proto 를 다음과 같이 수정해 주자. syntax = "proto3"; package Protocol; import "Enum.proto"; import "Struct.proto"; message C_LOGIN { } message S_LOG..

[C++ 게임 서버] 5-9. 패킷 자동화 #2 핵심 : 1. 파이썬과 jinja2 를 이용해, 패킷 핸들러 코드를 자동으로 생성해 보자. 2. 이 포스팅에서 만든 ProtoParser 는 Protocol.proto 의 패킷 명세를 읽어 PacketHandler 의 코드를 자동으로 생성한다. 저번 시간에 패킷 자동화를 위한 밑작업(?) 을 보여준 바 있다. 사실 제대로 패킷 자동화를 구축하기 위해서는, data-driven 하게 작업이 이루어져야 할 것이다. 간단한 Flow 를 생각하면 다음과 같다 : Protocol.proto 에 우리가 원하는 패킷(메시지)을 선언한다. 자동화 툴이 돌아가서 Packet 과 PacketHandler 클래스를 생성한다. 프로그래머는 각 패킷에 대한 커스텀 동작만 직접 구..