-
스파르타) The Last Rollback (D-25, Node.js 게임 서버 최종 프로젝트) - timerTIL-sparta 2024. 8. 3. 03:35
> 과제 진행 간 완료한 사항 및 문제점과 해결 과정을 정리해보았다.학습 키워드: Node.js, Unity, C#
과제 진행 사항
1) 라운드 전환, 몬스터 목록 전송, 낮 라운드 타이머 등:
- (상세 작업 내용은 위 Issue 참고)
2) 낮 라운드 타이머 기능:
현재 게임의 기획은 준비 라운드인 낮 라운드와 전투 라운드인 밤 라운드를 일정 횟수만큼 번갈아가며 반복하는 구조로 되어있다. 여기서 낮 라운드에 제한 시간을 두기로 했는데, 각 클라이언트의 타이머 및 서버의 타이머를 일치시켜야하는 부분을 고민해보게 되었다. 기능 구현에는 setTimeout을 사용하기로 했는데, 처음에는 여러 세션이 setTimeout을 했을 때 서버에 부담이 갈까 싶었으나 수백개의 세션이 돌아갈 때 각 세션에서 낮 라운드 타이머는 하나씩만 돌아가며, 타이머 자체가 별다른 무거운 작업을 실행하지는 않을 것이기 때문에 영향이 미미할 것이라고 판단했다.
일단 타이머의 시간은 세션 내 모든 클라이언트가 동일한 값을 공유해야하고, 실제로 라운드를 시작시키려면 이 값을 서버에서 관리해야한다. 그래서 서버에서 setTimeout을 호출하여 30초 후에 밤 라운드 시작 패킷을 보내도록 설정하고, 동시에 타이머가 시작한 시점의 timestamp와 설정된 시간을 타이머 설정 패킷에 담아 보내주도록 설정했다. 클라이언트가 타이머 패킷을 수신하면 받은 타이머의 시간과 서버의 시작 timestamp, 수신 시 timestamp를 계산하여 실제 서버의 남은 시간을 화면에 출력하도록 설정했다.
// dungeon.class.js (서버) ... setDayRoundTimer() { (async () => { setTimeout(() => { this._isNight = true; this.notifyAll(payloadTypes.S_NIGHT_ROUND_START, {}); }, DAY_DURATION); })(); (async () => { const data = { startTime: Date.now(), milliseconds: DAY_DURATION, }; this.notifyAll(payloadTypes.S_DAY_ROUND_TIMER, data); })(); } ...
// DungeonManager.cs (클라이언트) ... public void SetTimer(ulong timestamp, uint milliseconds) { ulong now = (ulong) DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); float time = (float) (milliseconds - (now - timestamp)) / 1000; uiTimer.SetCurrentTime(time); uiTimer.gameObject.SetActive(true); uiTimer.StartTimer(); } ...
추가로 고려할 사항은 클라이언트가 타이머 패킷을 수신하는 시점이 이미 타이머가 조금 흘러간 시점이라는 부분인데, ping 기능을 도입하여 latency를 계산하고 그만큼 setTimeout 실행을 실짝 늦춰야 하는 건가 싶다. 또한, 위 방식으로 구현한 타이머에는 한 가지 문제점이 있는데, setTimeout은 event loop에 blocking 작업이나 GC 등으로 인해 지연될 수가 있기 때문에 정확한 시간으로 동기화가 불가능하다. 추후 MVP 기능 구현 완료 후 여유가 생기면 이를 해결할 방법이 있는지 알아봐야겠다.
--
REFERENCES:> 프로젝트 repo
728x90'TIL-sparta' 카테고리의 다른 글
[WSL] WSL 설치 후 WiFi 연결이 안되는 문제 (Windows 11 Home) (0) 2024.08.04 스파르타) The Last Rollback (D-24, Node.js 게임 서버 최종 프로젝트) (0) 2024.08.03 스파르타) The Last Rollback (D-26, Node.js 게임 서버 최종 프로젝트) (0) 2024.08.01 스파르타) The Last Rollback (D-27, Node.js 게임 서버 최종 프로젝트) (0) 2024.07.31 스파르타) The Last Rollback (D-28, Node.js 게임 서버 최종 프로젝트) (0) 2024.07.31