대형 프로젝트 - C# + 유니티로 만드는 MMORPG 게임 개발/(6) 라이브서비스

2D MMO 라이브 서비스 - (2 - 3) 게임 구조 변경

monstro 2025. 9. 30. 20:07
728x90
반응형

- 개요

기존의 프로젝트에서는 단일 GameRoom을 사용하는 구조로 진행되었습니다.

그러나 대형 서비스에 적합하지 않으므로 해당 구조를 Zone을 사용하는 구조로 변경해보겠습니다.

다만, 한번에 전체를 수정하기 보다는 단계별로 수정해보도록 하겠습니다.

수정사항은 다음과 같습니다.

  • 1) Recv하는 클라이언트 세션은 N개 
  • 2) 게임로직을 담당하는 스레드 1개 
  • 3) 클라이언트로 Send하는 스레드 1개 
  • 4) DB관련 로직을 수행하는 메인 스레드 1개 

 

1) GameLogic 클래스

RoomManager 클래스에서 GameLogic 클래스로 변경

 

기존의 RoomManger 클래스를 위와 같이 GameLogic 클래스로 변경하였습니다.
GameLogic 클래스가 JobSerializer 클래스를 상속받도록 수정하여
작업단위마다 Lock을 걸어 처리하지 않고 작업단위(Job)를 큐에 집어넣어 처리할 수 있도록 수정하였습니다.

 

2) ClientSession_PreGame 클래스

 

HandleEnterGame 함수의 로직을 위와 같이 수정합니다.

로컬 플레이어를 입장시키는 Job을 GameRoom의 큐에 집어넣는 방식으로 수정하였습니다.

 

3) ClientSession 클래스

 

지역변수 2개를 추가합니다.

ClientSession에서 패킷을 생성하고 Send하는 역할을 한번에 수행하였지만,

역할을 나눠 패킷을 예약하는 함수와 예약된 패킷을 Send하는 함수로 분리하여 수행합니다.

  • _lock : Lock으로 사용하여 패킷을 컨테이너에 저장 / 컨테이너를 복사하는 상황에서 사용
  • _reservedQueue : 패킷을 저장할 컨테이너

 

 

Send 함수의 로직을 위와 같이 수정합니다.

Lock을 걸고 생성된 패킷을 컨테이너에 저장하는 동작을 수행하도록 설정합니다.

 

 

Flush 함수를 새롭게 추가하였습니다.

Lock을 걸어 컨테이너를 복사하고 복사한 컨테이너를 Send합니다.

 

 

OnDisconnected 함수를 위와 같이 수정하였습니다.

GameRoom에 존재하는 특정 플레이어를 찾는 Job을 GameRoom의 큐에 집어넣는 방식으로 수정하였습니다.

 

4) SessionManager 클래스

 

GetSessions 함수를 위와 같이 추가하였습니다.

Lock을 걸어 Manager에 의해 관리되는 ClientSession들을 복사하여 반환합니다.

 

5) 메인 Program 클래스

 

위와 같이 3개의 함수를 추가하였습니다.

  • GameLogicTask 함수 : GameLogic 클래스의 Update 함수를 호출
    • GameLogic의 Job을 수행하는 스레드를 생성
    • Job을 전부 수행했다면 Sleep 함수를 호출하여 CPU의 낭비를 최소화
  • DbTask 함수 : DbTransaction 클래스의 Update 함수를 호출
    • DB의 Job은 메인 스레드에서 수행
    • Job을 전부 수행했다면 Sleep 함수를 호출하여 CPU의 낭비를 최소화
  • NetworkTask 함수 : ClientSession 인스턴스의 FlushSend 함수를 호출
    • ClientSession의 Job을 수행하는 스레드를 생성
    • Job을 전부 수행했다면 Sleep 함수를 호출하여 CPU의 낭비를 최소화

 

 

Main 함수의 로직을 위와 같이 수정하였습니다.

우선, ID가 1인 GameRoom의 생성을 위한 Job을 GameRoom의 큐에 추가합니다.

이후 GameLogicTask를 위한 스레드 + NetworkTask를 위한 스레드를 생성합니다.

DbTask는 메인 스레드에서 수행합니다.

 

- 최종 실행 결과

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

 

728x90
반응형