Amazon Web Services 한국 블로그
Amazon GameLift 시작하기
올해 초에 처음 발표된 Amazon GameLift는 세션 기반의 멀티 플레이어 게임 서비스를 손쉽게 구축하고 운영하기 쉽도록 도와주는 관리형 서비스입니다. 지난 2월 블로그 글을 통해서 Amazon Lumberyard에 기본적으로 포함된 멀티플레이어 게임 샘플을 GameLift상에서 돌려보는 방법에 대한 소개를 드린 바 있습니다.
또한 지난 9월 Gaming On AWS 행사를 통해서 Amazon GameLift Deep-dive 강연에서 GameLift에 대해 자세한 내용을 다루었습니다. 이번 글에서는 좀 더 구체적으로 여러분이 만든 게임 서버를 직접 GameLift에 올려서 사용하는 방법과 게임 클라이언트가 GameLift의 Fleet에 접근하는 방법에 대해 다루어 보도록 하겠습니다.
Amazon GameLift 복습하기
GameLift 연동 방법 설명에 앞서, GameLift의 전체적인 개념을 기술적인 관점에서 다시 한 번 정리하고 넘어가도록 하겠습니다. 온라인 게임을 서비스하기 위해서는 크게 3가지 측면에서의 준비가 필요합니다.
첫번째는 플레이어들이 직접 실행하여 게임을 즐길 수 있도록 하는 게임 클라이언트고, 두번째는 다수의 게임 클라이언트들의 접속을 받아서 멀티플레이를 중계해주는 게임 서버입니다. 세번째는 게임 클라이언트들의 인증처리뿐만 아니라 게임 서버들을 제어하고 모니터링 할 수 있도록 운영을 도와주는 게임 서비스 플랫폼입니다. 바로 이 게임 서비스 플랫폼 역할에 더하여 게임 서버들의 확장/축소(scaling)를 도와주는 것이 GameLift입니다. (여러분들의 게임 서버를 AWS가 만들어 주는 것이 아닙니다.)
게임 서버를 호스팅 하기 위해서는 직접 개발한 게임 서버 빌드로부터 플릿을 생성하면 됩니다. 플릿을 생성하면 처음에는 초기 설정한 대수만큼의 EC2 인스턴스가 게임 서버를 호스팅하게 됩니다. (물론, 이후에는 GameLift의 Auto-scaling 기능을 통해 인스턴스 수를 자동으로 확장/축소할 수 있습니다.)
플릿 생성시에 하나의 EC2 인스턴스가 몇 개의 게임 서버 프로세스를 호스팅할지 정할 수 있습니다. 기본적으로 하나의 게임 서버 프로세스는 하나의 게임 세션을 맡아서 처리 합니다. 즉, 게임 서버 작성시에 하나의 게임 세션을 처리할 수 있도록 구현하면 됩니다. (참고: 현재 하나의 게임 세션당 받을 수 있는 최대 플레이어 세션 제한은 250명 입니다.) 게임 서버의 워크로드와 인스턴스 성능에 따라 다르지만 하나의 인스턴스는 적게는 수십개, 많게는 수백개의 게임 세션을 호스팅 하도록 설정하는 것이 일반적입니다.
GameLift 플릿이 게임 세션을 생성 가능한 상태인 Active상태가 되면 게임 클라이언트는 플릿에 직접 요청(게임 세션 생성, 게임 세션 내 플레이어 슬롯 예약, 게임 세션에 참여 등)할 수 있습니다. 당연히, 게임 클라이언트는 EC2인스턴스의 상태를 전혀 몰라도 됩니다. 단지, 어느 플릿에 접근하면 되는지에 대한 정보만 알면 되기 때문입니다.
Amazon GameLift SDK 사용하기
GameLift를 사용하기 위해서는 2가지 종류의 SDK를 사용하여야 합니다. 게임 서버는 GameLift 전용 Server SDK를 사용하여 통합작업을 하면 되지만 게임 클라이언트의 경우는 GameLift 전용 SDK가 따로 존재하는 것이 아니라 기본적으로 프로그래밍 언어별로 제공되는 AWS SDK를 사용하면 됩니다.
지난 블로그 글을 통해 AWS C++ SDK 사용하는 법을 소개 드린 적이 있습니다만, C++언어 뿐만 아니라 AWS SDK가 제공하는 타 언어별 SDK를 사용하셔도 됩니다. 즉, 게임 클라이언트 프레임워크의 상황에 맞게 적합한 AWS SDK를 사용하시면 됩니다.
게임 클라이언트와 게임 서버간의 통신에는 TCP 및 UDP 프로토콜을 사용하실 수 있으며, 메시지 전달을 위한 패킷은 직접 구현하시거나 기존의 유명한 데이터 직렬화 및 패킷 생성 도구인 Google Protocol Buffers나 MessagePack를 활용하셔도 좋습니다.
게임 클라이언트와 게임 서버, GameLift 서비스간의 API 레벨에서의 전체적인 상호 작용은 다음 그림을 참고하시기 바랍니다.
GameLift Server SDK를 통해서 게임 서버 연동하기
그럼 이제 본격적으로 여러분들의 게임 서버에 GameLift Server SDK를 연동하는 방법에 대해 알아보겠습니다. GameLift Server SDK는 C++로 작성된 게임 서버와 통합할 수 있습니다. (향후 C# 프로그래밍 언어도 지원할 예정입니다.)
지원하는 운영체제는 Windows Server 및 Amazon Linux이며, 사용하고자 하는 운영체제에 맞춰 빌드해야 합니다. Windows Server의 경우에는 Visual Studio 2013 이상, Linux의 경우에는 GCC 4.9 이상의 버전이 필요합니다. 추가로 CMAKE가 필요하며 자세한 빌드 방법에 대해서는GameLift Server SDK내에 포함된 README.md 파일을 참고하시기 바랍니다.
GameLift Server SDK 빌드가 완료되면 생성되는 라이브러리 파일(Windows의 경우 *.dll 및 *.lib, Linux의 경우에는 *.a 또는 *.so)과 GameLift Server SDK의 include 디렉토리에 포함된 헤더파일들을 게임 서버가 위치한 프로젝트로 복사하시기 바랍니다. Visual Studio의 경우에는 프로젝트 설정에서 해당 파일들의 위치를 지정해주시고, GCC를 사용하는 경우에는 Makefile 또는 CMakeLists.txt 파일을 통해 해당 라이브러리와 헤더 파일의 위치를 게임 서버 프로젝트에서 참조할 수 있게 지정해주시기 바랍니다. GameLift Server SDK가 연동된 게임 서버 프로젝트 예제를 참고하시기 바랍니다.
GameLift Server SDK에서 제공하는 게임 서버전용 API는 다음과 같으며, 여러분들이 제작하는 게임 서버에서 이 API를 호출하는 부분과 GameLift서비스가 게임 서버에게 요청하는 콜백 함수에 대한 구현을 하시면 됩니다.
- 게임 서버가 GameLift 서비스에 요청하는 API
-
ProcessReady()
– 게임 서버가 준비 되었음을 GameLift 서비스에게 알림. 이 호출이 성공적으로 완료되면 플릿 상태가 Active로 됨. -
ActivateGameSession()
– 게임 세션이 준비완료 되었음을 GameLift 서비스에게 알림. 이후에 플레이어의 접속을 받아 게임 세션에 참여 시키면 됨. -
AcceptPlayerSession()
– 접속한 게임 클라이언트가 정상적인 플레이어라면 이 API 호출을 통해 GameLift 서비스에게 알림. 이를 통해 GameLift 서비스는 플레이어가 게임 세션에 참여했음을 알게됨. -
RemovePlayerSession()
– 게임 클라이언트가 게임 세션에서 나갔을 때, 게임 서버가 GameLift 서비스에게 통보하는 API. -
TerminateGameSession()
– 게임 세션이 종료되었을 때 GameLift 서비스에게 알려서 게임 세션을 종료하도록 하는 API. -
ProcessEnding()
– 게임 서버 프로세스가 종료되었음을 알리는 API. 이 경우 GameLift 서비스가 해당 게임 서버를 종료시키고 새로운 게임 서버 프로세스를 생성하여 추후의 게임 세션 요청에 대해 준비하도록 함.
-
- GameLift 서비스가 게임 서버에게 요청하는 콜백함수
-
onHealthCheck()
– 주기적으로 GameLift 서비스가 게임 서버가 살아있는지 호출하는 함수로 게임 서버가 정상이라면 true를 리턴해주면 됨. -
onStartGameSession()
– 게임클라이언트가 GameLift 서비스에 게임 세션 생성을 요청하게 되면, GameLift 서비스가 게임 서버에게 이 콜백 함수를 통해 통지함. 게임 서버는 게임 세션 준비가 완료되면 ActivateGameSession() API 호출을 통해 게임 세션 준비가 완료되었음을 알리면 됨.
-
구체적인 사용 샘플 코드 구현을 참고하시기 바랍니다. 이런 방식으로 GameLift Server SDK를 활용한 게임 서버의 빌드가 준비되었다면 AWS CLI를 통하여 GameLift에 빌드를 올려야 합니다. 기본적으로 생성된 게임 서버 실행파일 이외에도 의존성 있는 파일들(DLL 등)이 있다면 함께 하나의 폴더 내에 모아주시기 바랍니다. 준비가 완료 되면 다음과 같은 명령어를 통해 GameLift상에 빌드를 올릴 수 있고, 업로드가 완료되면 AWS 콘솔 상에서 확인이 가능합니다.
$ aws gamelift upload-build --name “빌드 이름” --build-version “빌드 버전” --build-root “빌드가 있는 폴더” --operating-system <운영체제: WINDOWS_2012 또는 AMAZON_LINUX> --region <리전>
업로드된 게임 서버 빌드를 보실 수 있습니다.
이제 해당 빌드로부터 플릿을 생성할 수 있습니다. 빌드를 선택하고 플릿 생성하기를 진행하게 되면 몇 가지 설정을 하여야 합니다. 대표적으로 EC2 인스턴스 타입 설정, 실행파일 이름, 게임 서버 프로세스 수, 열어둘 포트 번호 및 프로토콜 등을 설정하게 됩니다. 또한 Auto-scaling 정책을 설정하게 되는데 이 정책은 플릿 생성후에 수정할 수도 있습니다. 모든 설정을 마쳤다면, 플릿을 생성하시기 바랍니다.
기본적으로 게임 클라이언트는 플릿 ID를 통해 플릿에 접근하게 됩니다. 하지만, ALIAS기능을 활용하기를 추천드립니다. ALIAS는 플릿의 ID를 바라보게 할 수 있고 이를 사용하게 되면, 게임 클라이언트는 ALIAS ID를 통해서 지정된 플릿에 접근할 수 있습니다. 만일 게임 클라이언트 수정 없이 새로운 플릿으로 접속을 유도하고 싶다면, ALIAS가 바라보는 플릿의 ID만 바꾸면 되기 때문에, 중단 없이 새로운 플릿으로 접속을 유도할 수 있습니다. (즉, ALIAS 기능을 통한 무중단 배포가 가능함을 의미합니다.)
AWS SDK를 통해서 게임 클라이언트 연동하기
게임 서버가 플릿에 올라가 있는 상황이라면, 게임 클라이언트가 플릿에 접속해서 게임 세션에 참여할 수 있습니다. GameLift 연동 가능한 게임 클라이언트 준비는 앞서 설명 드린 게임 서버 연동에 비해서는 쉬운 편입니다. 또한, 프로그래밍 언어나 프레임워크 선택도 자유로운 편입니다. 그 이유는 AWS SDK를 쓸 수 있는 환경이기만 하면 되기 때문입니다.
즉, 각 프로그래밍 언어별로 존재하는 AWS SDK를 여러분들의 게임 클라이언트에서 사용하도록 설정하면 됩니다. 게임 클라이언트 제작시 가장 많이 사용되는 프로그래밍 언어인 C++의 경우에는 얼마전 정식 버전이 발표된 AWS C++ SDK를 사용하면 되며, 자세한 사용 방법에 대해서는 지난 블로그 포스팅에서 다룬 바 있습니다. 예를 들어, 유명한 오픈소스 게임 엔진인 Cocos2d-x에 AWS C++ SDK를 연동하여 GameLift를 사용하는 샘플 프로젝트를 참고하시기 바랍니다.
GameLift 연동을 위해서 게임 클라이언트를 구현시 사용하게 되는 API는 다음과 같습니다.
-
CreateGameSession()
– GameLift서비스에 게임 세션 생성을 요청하는 API. 대상 플릿ID 또는 ALIAS ID 설정하고 해당 게임 세션이 최대로 수용할 수 있는 플레이어 세션 수를 지정. 요청에 대한 응답으로 게임 세션 ID및 해당 게임 세션을 호스팅하는 게임 서버의 IP주소와 포트 번호를 받게 됨. -
SearchGameSessions()
– 이미 만들어진 게임 세션이 있다면, 조건식으로 해당 게임 세션을 찾는 API. 여러가지 조건으로 게임 세션 검색이 가능하며, 자세한 조건식 작성 방법은 API 문서에서 확인 가능. 요청에 대한 응답은 위의 CreateGameSession()과 같음. -
CreatePlayerSession()
– 참여하고자 하는 적합한 게임 세션을 찾거나 만든 후에, 플레이어 참여를 시킬 수 있도록 플레이어 세션을 생성하는 API. 요청에 대한 응답으로 플레이어 세션 ID를 발급 받게 되며, 이후에 실제 게임 서버에 접속을 요청하면 됨.
이외에도 게임 클라이언트가 사용할 수 있는 API가 있지만 대부분의 경우에는 위의 3종류 API만 사용하게 됩니다. 전체적인 API 상호 작용 과정은 아래 그림을 참고하시기 바랍니다.
게임 클라이언트가 요청하는 GameLift API는 그에 맞는 권한이 IAM을 통하여 부여 되어야 합니다. IAM 권한을 모든 사용자에게 부여하기 힘든 환경이라면 제3자 인증 주체(Amazon, Google, Facebook 등)와의 연방화(Federation)을 통해서 권한을 부여할 수 있습니다. 제 3자를 통한 인증이 힘든 상황이라면 Amazon Cognito UserPool을 활용(https://aws.amazon.com/ko/blogs/korea/how-to-own-user-auth-service-using-amazon-cognito/)하여 직접 인증 서비스를 구축하실 수도 있습니다.
이렇게 여러분의 게임 서버 및 게임 클라이언트를 GameLift에 연동함으로써, 게임 클라이언트는 플릿에 게임 세션을 요청하고 적합한 게임 세션을 찾은 후에 플레이어 세션 생성을 통해 게임에 참여할 수 있게 됩니다. 이제 직접 GameLift의 웹 콘솔을 통하여 서비스 상태 모니터링 및 플릿의 설정을 원하는대로 제어해 보시기 바랍니다.
필요에 따라 수동으로도 게임 서버를 호스팅하는 인스턴스의 수를 조정할 수 있으며, 게임 세션 및 플레이어 세션들의 세부 상태에 대한 확인과 제어가 가능 합니다. 이렇게 GameLift를 통하여 세션형 멀티 플레이어 게임의 서버 관리 부담을 덜어낼 수 있을 뿐만 아니라, 사용자의 상황에 맞게 플릿의 인스턴스 수가 자동으로 확장/축소 되는 기능을 통해 손쉽게 게임 서비스를 운영할 수 있습니다.
본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 구승모 솔루션즈 아키텍트께서 작성해주셨습니다.