로컬에서 게임 서버 디버깅 및 PlayFab과 통합
개요
PlayFab 멀티 플레이어 게임 서버는 PlayFab GSDK(게임 서버 SDK)와 통합되어야 합니다. 또한 게임 서버는 PlayFab 멀티 플레이어 플랫폼에서 컨테이너화된 응용 프로그램으로 실행됩니다.
컨테이너화된 응용 프로그램으로 실행하면 Azure의 PlayFab 플랫폼과 일치하는 환경에서 서버를 로컬에 실행하고 디버깅할 수 있습니다. 이를 통해 빠른 개발 반복을 쉽게 할 수 있습니다. 이 문서는 PlayFab 게임 서버가 플랫폼 요구 사항을 준수하는지 확인하는 데 도움이 됩니다.
PlayFab 로컬 디버깅 도구 집합에는 GSDK에 대한 모의 응답을 제공하고 게임 서버가 GSDK와 올바르게 통합되어 있는지 여부를 확인하는 LocalMultiplayerAgent가 포함되어 있습니다. 모의 응답으로 VmAgent는 PlayFab 멀티 플레이어 플랫폼에서 수명 주기 동안 다양한 상태로 게임 서버를 순환합니다.
게임 서버를 컨테이너화된 애플리케이션으로 실행하도록 에이전트를 구성할 수 있습니다. 게임 서버가 모든 필수 종속성으로 패키징되고 PlayFab 멀티 플레이어 플랫폼에서 문제 없이 실행되는지 확인합니다. LocalMultiplayerAgent는 Windows 또는 Linux 게임 서버에서 작동할 수 있습니다.
기본 설정 - Windows
GSDK와 게임 서버를 통합하고 이를 빌드합니다. 자세한 내용은 게임 서버와 PlayFab GSDK(게임 서버 SDK) 통합을 참조하세요.
게임 서버와 서버의 종속성을 zip 보관 파일로 압축합니다. 컨테이너 모드에서 올바르게 실행하려면 컨테이너 이미지에 포함되지 않은 시스템 DLL이 zip 보관 파일에 포함되어야 합니다. 자세한 내용은 필수 시스템 DLL 확인을 참조하세요.
참고 항목
zip 폴더 내의 폴더를 압축하는 일반적인 실수를 저지르지 않도록 주의하세요. 압축한 후 zip 폴더를 검색하여 압축 소프트웨어가 추가 파일 계층 구조의 계층을 추가하지 않았는지 다시 확인해야 합니다.
로컬 디버깅 도구 집합을 다운로드하여 원하는 폴더(예: C:\PlayFabVmAgent)에 압축을 풉니다.
LocalMultiplayerAgent MultiplayerSettings.json 생성기 json 파일을 검사하는 동안 아래에서 다음 옵션에 대해 자세히 읽어보세요.
압축을 푼 폴더의 위치로 이동하여 텍스트 편집기에서 MultiplayerSettings.json 파일(예: Visual Studio Code)을 엽니다. 다음 속성을 업데이트합니다.
-
LocalFilePath
- 워크스테이션에서 이전에 만든 게임 서버 자산 zip 파일에 대한 전체 로컬 경로입니다. 예: D:\\MyAmazingGame\\asset.zip(JSON 형식을 위해 백슬래시를 이스케이프해야 함) -
StartGameCommand
- 컨테이너 내의 게임 서버 실행 파일에 대한 전체 경로입니다. 예를 들어, 실행 파일 이름이 mygame.exe라고 하면 샘플 경로는 C:\\Assets\\mygame.exe가 됩니다. StartGameCommand의 경로는 프로세스와 컨테이너에 따라 다릅니다. 컨테이너의 StartGameCommand 경로는 컨테이너 또는 자산 폴더의 리소스에 대한 절대 경로입니다. 프로세스의 StartGameCommand 경로는 작업 디렉터리가 지정된 첫 번째 자산이 되는 상대 경로입니다. -
PortMappingsList
- 게임을 실행하는 동안 게임에 사용할 수 있는 포트입니다.NodePort
은(는) 워크스테이션에서 열리는 포트이고GamePort.Number
은(는) 컨테이너에서 실행할 때 게임 서버가 바인딩해야 하는 포트입니다. 게임 서버가 클라이언트를 수신 대기하는 프로토콜 및 포트와 일치하도록 GamePort 섹션을 업데이트합니다. 게임 서버에 여러 포트가 필요한 경우 기존 포트 구성을 복사하여 붙여넣고NodePort
를 늘린 다음,GamePort.Number
및GamePort.Name
을 필요한 포트로 업데이트합니다. 프로세스로 실행할 때GamePort.Number
는 무시되며 프로세스는 NodePort에 바인딩되어야 합니다. 두 가지 경우를 모두 처리하려면 다음 중 하나를 수행합니다.- 포트를 동일한 값으로 설정
- 바인딩할 올바른 포트를 항상 반환하는
GamePort.Name
키가 있는 값에 대해 런타임 시 GSDK 구성을 확인합니다.
-
MultiplayerSettings.json 파일에는 편집할 수 있는 추가 필드가 있습니다.
-
ResourceLimits
(선택 사항) - 지정된 경우 docker는 CPU/메모리 사용량을 제한합니다. 경고: 서버에서 허용된 메모리를 초과하면 서버가 종료됩니다. ResourceLimits는 컨테이너 모드에서만 지정할 수 있습니다. -
SessionCookie
(선택 사항) - RequestMultiplayerServer API 호출의 일부로 게임 서버에 전달되는 모든 세션 쿠키입니다. -
OutputFolder
(선택 사항) - 출력 및 구성 파일을 생성할 드라이브나 폴더로의 절대 경로입니다. 이 경로에서 게임 서버가 추출되므로 사용 가능한 공간이 충분한지 확인하세요. 지정하지 않은 경우에는 에이전트 폴더가 사용됩니다. -
MountPath
- 자산을 탑재할 컨테이너 내의 경로입니다. 프로세스 모드에서 실행할 때는 이 필드를 지정할 필요가 없습니다. 샘플 값 C:\\Assets를 사용하는 것이 좋습니다(JSON 형식을 위해 백슬래시를 이스케이프해야 함). -
AgentListeningPort
- 에이전트가 게임 서버와 통신하기 위해 바인딩할 포트를 지정합니다. 열려 있는 모든 포트가 작동합니다. 56001에 다른 프로세스 바인딩이 있으면 이 값을 변경하거나 다른 프로세스를 중지해야 합니다.
-
GSDK 통합 확인
-
MultiplayerSettings.json 파일에서
RunContainer
를false
로 설정합니다. - Powershell 창에서(관리자 권한으로 실행):
- 작업 디렉터리를 도구 집합의 압축을 푼 폴더로 변경합니다.
- LocalMultiplayerAgent.exe를 실행합니다. 이 때, LocalMultiplayerAgent는 http 수신기를 설정하고 게임 자산의 압축을 푼 다음, 별도의 프로세스에서 게임 서버를 시작합니다. 그런 다음 LocalMultiplayerAgent는 게임 서버와 통합된 GSDK의 하트비트를 기다립니다.
- GSDK가 올바르게 통합되면 LocalMultiplayerAgent는 다음 출력을 출력합니다.
-
CurrentGameState - Initializing
(이것은 선택 사항이며 게임 서버가GSDK::ReadyForPlayers
을(를) 직접 호출하고GSDK::Start
을(를) 호출하지 않는 경우 표시되지 않을 수 있습니다.) CurrentGameState - StandingBy
CurrentGameState - Active
CurrentGameState - Terminating
-
- 종료 콜백이 올바르게 설정되면 상태가 종료로 설정된 직후 게임 서버가 종료됩니다. PlayFab 플랫폼에서 비정상적 종료를 방지하기 위해 게임 서버가 종료되는지 확인하는 것이 중요합니다.
- LocalMultiplayerAgent도 게임과 함께 종료되어야 합니다.
게임에 대한 연결 테스트
게임 서버 실행 파일이 실행 중이고 LocalMultiplayerAgent가 CurrentGameState - Active
를 출력할 때, 게임 서버가 수신 대기 중인 IP 주소 127.0.0.1과 포트 NodePort
를 사용하여 게임 서버에 연결할 수 있습니다.
NumHeartBeatsForActivateResponse
하트비트 후, LocalMultiplayerAgent는 게임 서버를 대기 상태에서 활성 상태로 이동하도록 요청합니다. 그런 다음 NumHeartBeatsForTerminateResponse
하트비트 후, LocalMultiplayerAgent는 게임 서버를 활성 상태에서 종료됨으로 이동하도록 요청합니다. 이 동작은 MultiplayerSettings.json 파일의 값을 업데이트하여 조정할 수 있습니다.
컨테이너화 확인
컨테이너 세계를 처음 접한 분이라면 여기에서 소개를 확인할 수 있습니다.
필수 구성 요소
- 2018년 4월(1803) 업데이트를 완료한 Windows 10 Pro 이상.
- Docker를 다운로드합니다. 또는 Docker 웹 사이트의 기본 페이지에서 Docker를 다운로드할 수 있습니다.
설정
- Docker가 Windows 컨테이너를 사용하도록 설정되어 있는지 확인
- Powershell 창에서(관리자 권한으로 실행):
- 도구 집합의 압축을 푼 폴더로 이동합니다.
- Docker 네트워크를 설정하는 Setup.ps1을 실행하고, 방화벽 규칙을 추가하여 LocalMultiplayerAgent와 통신한 다음, Microsoft/PlayFab-Multiplayer에서 PlayFab Docker 이미지를 가져옵니다. 스크립트가 처음 실행될 때 컨테이너 이미지를 다운로드하는 데 몇 분 정도 걸릴 수 있습니다.
참고 항목
이 설정을 성공적으로 실행하려면 사용자가 설치한 모든 타사 바이러스 백신 프로그램(예: McAfee, Norton, 또는 Avira)의 방화벽을 구성해야 할 수 있습니다.
컨테이너 내에서 게임 서버 실행
-
MultiplayerSettings.json 파일에서
RunContainer
를true
로 설정합니다. - 도구 집합의 압축을 푼 폴더(C:\PlayFabVmAgent)에서 Powershell 창(관리자 권한으로 실행)을 열고
LocalMultiplayerAgent.exe
를 실행합니다. 이렇게 하면 컨테이너 내의 게임 서버가 시작됩니다. 결국 위의 GSDK 통합 확인 섹션과 마찬가지로 Powershell 창에서 게임 상태 변경 출력을 볼 수 있습니다.
컨테이너 내에서 실행 중인 게임 서버에 대한 연결 테스트
LocalMultiplayerAgent 출력이 CurrentGameState - Active
를 출력할 때, IP 주소 127.0.0.1 및 MultiplayerSettings.json 파일에 지정된 NodePort
(기본적으로 56100)와 동일한 포트를 사용하여 게임 서버에 연결합니다.
NumHeartBeatsForActivateResponse
하트비트 후, LocalMultiplayerAgent는 게임 서버를 대기 상태에서 활성 상태로 이동하도록 요청합니다. 그런 다음 NumHeartBeatsForTerminateResponse
하트비트 후, LocalMultiplayerAgent는 게임 서버를 활성 상태에서 종료됨으로 이동하도록 요청합니다. 이 동작은 MultiplayerSettings.json 파일의 값을 업데이트하여 조정할 수 있습니다.
Linux 컨테이너에서 LocalMultiplayerAgent 사용
LocalMultiplayerAgent를 사용하면 Windows용 Docker를 사용하여 Windows의 컨테이너에서 실행하여 Linux 게임 서버를 디버그할 수 있습니다. Windows에서 Linux 컨테이너를 실행하는 방법에 대한 자세한 내용은 여기에서 확인할 수 있습니다. 기본적으로 필요한 것은 -lcow 매개 변수를 사용하여 에이전트를 실행하고 LocalMultiplayerSettings.json 파일을 올바르게 구성하는 것입니다.
Windows에서 컨테이너화된 Linux 게임 서버를 실행하려면 다음 단계를 수행해야 합니다.
- GitHub의 릴리스 페이지에서 최신 버전의 LocalMultiplayerAgent 다운로드
- Windows에 Docker 데스크톱 설치
- Linux 컨테이너에서 실행 중인지 확인
- 하드 드라이브 중 하나를 탑재해야 하며 여기에서 지침을 찾을 수 있습니다.
- 게임 서버 이미지는 컨테이너 레지스트리에 게시하거나 로컬에서 빌드할 수 있습니다.
- "PlayFab"이라는 Docker 네트워크를 만드는
SetupLinuxContainersOnWindows.ps1
Powershell 파일 실행 -
LocalMultiplayerSettings.json 파일을 올바르게 구성합니다. 아래에서
MultiplayerSettingsLinuxContainersOnWindowsSample.json
에 포함된 샘플을 확인할 수 있습니다.
{
"RunContainer": true,
"OutputFolder": "C:\\output\\UnityServerLinux",
"NumHeartBeatsForActivateResponse": 10,
"NumHeartBeatsForTerminateResponse": 60,
"TitleId": "",
"BuildId": "00000000-0000-0000-0000-000000000000",
"Region": "WestUs",
"AgentListeningPort": 56001,
"ContainerStartParameters": {
"ImageDetails": {
"Registry": "mydockerregistry.io",
"ImageName": "mygame",
"ImageTag": "0.1",
"Username": "",
"Password": ""
}
},
"PortMappingsList": [
[
{
"NodePort": 56100,
"GamePort": {
"Name": "game_port",
"Number": 7777,
"Protocol": "TCP"
}
}
]
],
"SessionConfig": {
"SessionId": "ba67d671-512a-4e7d-a38c-2329ce181946",
"SessionCookie": null,
"InitialPlayers": [ "Player1", "Player2" ]
}
}
참고 사항:
RunContainer
를 true로 설정해야 합니다. Linux 게임 서버에서 필요합니다.- 게임 서버 docker 이미지 세부 정보를 사용하여
imageDetails
를 수정합니다. 이미지는 로컬로 빌드되거나(docker build 명령 사용) 원격 컨테이너 레지스트리에서 호스트될 수 있습니다.StartGameCommand
및AssetDetails
은(는) 선택 사항입니다. 모든 게임 자산 + 게임 서버 시작 명령은 해당 Dockerfile에 패키지될 수 있으므로 Docker 컨테이너를 사용할 때 일반적으로 사용하지 않습니다.- 마지막으로, Linux 컨테이너는 대/소문자를 구분하므로
OutputFolder
변수의 대/소문자 구분에 주의하세요. 대/소문자 구분이 잘못된 경우, 탑재 원본 경로 ‘/host_mnt/c/output/UnityServerLinux/PlayFabVmAgentOutput/2020-01-30T12-47-09/GameLogs/a94cfbb5-95a4-480f-a4af-749c2d9cf04b’를 생성하는 동안 오류와 유사한 Docker 예외가 표시될 수 있습니다. mkdir /host_mnt/c/output: 파일이 있습니다.
- 이전 단계를 모두 수행한 다음,
LocalMultiplayerAgent.exe -lcow
(lcow는 Linux Containers On Windows를 나타냄) 명령을 사용하여 LocalMultiPlayerAgent를 실행할 수 있습니다.
문제 해결
- 컨테이너 모드에서 게임 서버가 "Container ... exited with exit code 1"과 유사한 오류와 함께 즉시 종료되지만 프로세스 모드에서는 제대로 작동하는 경우. <자산 시스템에 필요한 시스템 DLL을 모두 포함했는지 확인하세요.
- 모든 로그는 MultiplayerSettings.json 파일에 지정된
OutputFolder
아래에 있습니다. LocalMultiplayerAgent는 시작할 때마다 타임스탬프를 폴더 이름으로 사용하여 새 폴더를 만듭니다. GSDK를 통해 내보낸 모든 게임 서버 로그는 GameLogs 폴더에 위치합니다.
컨테이너 내에서 게임 서버를 실행한 경우 디렉터리 계층 구조에서 자세히 살펴보아야 할 추가 수준이 있을 수 있습니다. - GSDK는 GameLogs 폴더에 디버그 로그를 기록합니다. 이러한 로그는 게임 서버의 로그 출력과 함께 GameLogs 폴더 내에 있습니다.
- 방화벽(Windows 및 기타 바이러스 백신)이 포트를 통해 트래픽을 허용하도록 구성되어 있는지 확인합니다.
- 다음과 같은 유사한 오류가 발생하는 경우:
Docker API responded with status code=InternalServerError, response={"message":"failed to create endpoint <container_name> on network playfab: hnsCall failed in Win32: The specified port already exists". It's likely there is already a container running on the specified port.
이 오류는 LocalMultiplayerAgent가 너무 일찍 종료되는 경우에 발생할 수 있습니다.docker ps
명령을 사용하여 실행 중인 컨테이너를 찾은 다음docker kill <container_name>
을 사용하여 종료합니다. -
Failed to find network 'playfab'
이 포함된 오류가 발생하는 경우 Setup.ps1을 다시 실행해 보세요. -
Unhandled Exception
오류가 발생하면 PowerShell을 관리자 권한으로 실행할 수 있습니다. -
OutputFolder
는 다른 시스템 변수가 차례로 사용할 수 있으므로 절대 경로를 사용했는지 확인합니다. 예를 들어 GSDK_CONFIG_FILE은 그런 종속성이 있으므로 여기에 상대 경로(또는 잘못된 값)가 있으면 게임 서버 구성 로드 오류가 발생할 수 있습니다.
알려진 제한
- 컨테이너는 디버깅이 끝날 때 종료되지 않을 수 있습니다. 이 경우 관리자 권한으로 다음 PowerShell 명령을 실행합니다. 이러한 명령은 LocalMultiplayerAgent에서 시작하지 않은 컨테이너를 포함하여 모든 컨테이너를 중지하고 제거합니다.
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)