> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 게임 서버 로컬 디버깅 및 PlayFab과의 통합

> PlayFab Game Server SDK(GSDK)와 PlayFab 멀티플레이어 게임 서버를 통합하고 통합을 확인 및 디버깅하는 방법을 설명합니다.

## 개요

PlayFab 멀티플레이어 게임 서버에는 [PlayFab Game Server SDK(GSDK)](/services/playfab/multiplayer/servers/integrating-game-servers-with-gsdk)와의 통합이 필요합니다. 또한, 게임 서버는 PlayFab Multiplayer 플랫폼에서 컨테이너화된 애플리케이션으로 실행됩니다.

컨테이너화된 애플리케이션으로 실행하면 Azure의 PlayFab 플랫폼과 일치하는 환경에서 로컬로 서버를 실행하고 디버그할 수 있습니다. 이를 통해 개발 반복 속도를 높일 수 있습니다. 이 문서는 PlayFab 게임 서버가 플랫폼 요구 사항을 준수하는지 확인하는 데 도움이 됩니다.

PlayFab 로컬 디버깅 도구 세트에는 GSDK에 대한 모의 응답을 제공하고 게임 서버가 GSDK와 올바르게 통합되었는지 확인하는 [LocalMultiplayerAgent](https://github.com/PlayFab/MpsAgent)가 포함되어 있습니다. 모의 응답을 통해 VmAgent는 PlayFab Multiplayer 플랫폼의 수명 주기에서 게임 서버를 다양한 상태로 순환시킵니다.

에이전트를 컨테이너화된 애플리케이션으로 게임 서버를 실행하도록 구성할 수 있습니다. 게임 서버가 필요한 모든 종속성과 함께 패키징되고 PlayFab Multiplayer 플랫폼에서 문제 없이 실행되는지 확인합니다. LocalMultiplayerAgent는 Windows 또는 Linux 게임 서버 모두에서 작동할 수 있습니다.

## 기본 설정 - Windows

* 게임 서버를 GSDK와 통합하고 빌드하세요. 자세한 내용은 [PlayFab Game Server SDK(GSDK)와 게임 서버 통합](/services/playfab/multiplayer/servers/integrating-game-servers-with-gsdk)을 참조하세요.
* 게임 서버와 해당 종속성을 zip 아카이브로 압축합니다. 컨테이너 모드에서 제대로 실행되려면 zip 아카이브에 컨테이너 이미지에 포함되지 않은 시스템 DLL이 포함되어야 합니다. 자세한 내용은 [필요한 시스템 DLL 확인](/services/playfab/multiplayer/servers/determining-required-dlls)을 참조하세요.

<Note>
  이 흔한 실수를 피하세요 - zip 내부의 폴더 *안*에 폴더를 실수로 압축하지 마세요. 압축 후 zip 폴더를 탐색하여 압축 소프트웨어가 파일 계층에 추가 레이어를 추가하지 않았는지 다시 확인하세요.
</Note>

* [로컬 디버깅 도구 세트](https://github.com/PlayFab/MpsAgent/releases)를 다운로드하고 선택한 폴더(예: *C:\PlayFabVmAgent*)에 추출합니다.

* [LocalMultiplayerAgent MultiplayerSettings.json Generator](https://github.com/PlayFab/MpsAgent/tree/main/LocalMultiplayerAgent/SettingsJsonGenerator) json 파일을 검토하는 동안 아래의 다음 옵션에 대해 자세히 알아보세요.

* 추출된 폴더 위치로 이동하여 텍스트 편집기(예: [Visual Studio Code](https://code.visualstudio.com/download))에서 *MultiplayerSettings.json* 파일을 엽니다. 다음 속성을 업데이트합니다:
  * `LocalFilePath` - 이전에 만든 게임 서버 자산 zip 파일에 대한 전체 로컬 경로(워크스테이션에서), 예: *D:\\\MyAmazingGame\\\asset.zip*(JSON 형식을 위해 백슬래시는 이스케이프해야 함).
  * `StartGameCommand` - 컨테이너 내 게임 서버 실행 파일의 전체 경로. 예를 들어 실행 파일 이름이 *mygame.exe*인 경우 샘플 경로는 *C:\\\Assets\\\mygame.exe*가 될 수 있습니다. StartGameCommand 경로는 Process와 Container에서 다릅니다. Container의 StartGameCommand 경로는 컨테이너 또는 asset 폴더의 리소스에 대한 절대 경로입니다. Process의 StartGameCommand 경로는 첫 번째 지정된 asset이 작업 디렉터리가 되는 상대 경로입니다.
  * `PortMappingsList` - 실행 중일 때 게임에서 사용할 수 있는 포트입니다. `NodePort`는 워크스테이션에서 열리는 포트이고, `GamePort.Number`는 컨테이너에서 실행할 때 게임 서버가 바인딩해야 하는 포트입니다. GamePort 섹션을 게임 서버가 클라이언트를 수신 대기하는 프로토콜 및 포트와 일치하도록 업데이트합니다. 게임 서버에 여러 포트가 필요한 경우 기존 포트 구성을 복사/붙여넣기하고 `NodePort`를 증가시킨 다음, `GamePort.Number`와 `GamePort.Name`을 필요한 포트로 업데이트합니다. 프로세스로 실행할 때 `GamePort.Number`는 무시되며, 프로세스는 NodePort에 바인딩해야 합니다. 두 경우를 모두 처리하려면 다음 중 하나를 수행하세요:
    * 포트를 동일한 값으로 설정
    * 런타임에 GSDK 구성에서 `GamePort.Name` 키로 값을 확인 - 이는 항상 바인딩할 올바른 포트를 반환합니다.

* *MultiplayerSettings.json* 파일에는 편집할 수 있는 추가 필드가 있습니다:
  * `ResourceLimits`(선택 사항) - 지정된 경우 docker가 CPU/메모리 사용량을 제한합니다. 경고: 서버가 허용된 메모리를 초과하면 종료됩니다. ResourceLimits는 container 모드에서만 지정할 수 있습니다.
  * `SessionCookie`(선택 사항) - [RequestMultiplayerServer API](xref:titleid.playfabapi.com.multiplayer.multiplayerserver.requestmultiplayerserver) 호출의 일부로 게임 서버에 전달되는 세션 쿠키.
  * `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`
* 종료 콜백이 올바르게 설정된 경우 상태가 terminating으로 설정된 직후 게임 서버가 종료됩니다. PlayFab 플랫폼에서의 비정상 종료를 피하기 위해 게임 서버가 종료되는지 확인하는 것이 중요합니다.
* **LocalMultiplayerAgent**도 게임과 함께 종료되어야 합니다.

### 게임에 대한 연결 테스트

게임 서버 실행 파일이 실행 중이고 **LocalMultiplayerAgent**가 `CurrentGameState - Active`를 인쇄하면 IP 주소 **127.0.0.1**과 게임 서버가 수신 대기 중인 포트 `NodePort`를 사용하여 게임 서버에 연결할 수 있습니다.

`NumHeartBeatsForActivateResponse` 하트비트 후, **LocalMultiplayerAgent**는 게임 서버가 standby에서 active로 이동하도록 요청합니다. 그런 다음 `NumHeartBeatsForTerminateResponse` 하트비트 후 **LocalMultiplayerAgent**는 게임 서버가 active에서 terminated로 이동하도록 요청합니다. 이 동작은 *MultiplayerSettings.json* 파일의 값을 업데이트하여 조정할 수 있습니다.

## 컨테이너화 확인

컨테이너 세계에 익숙하지 않은 경우 [여기](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/container-docker-introduction/)에서 소개를 확인할 수 있습니다.

### 사전 요구 사항

* 2018년 4월(1803) 업데이트가 있는 Windows 10 Pro(또는 그 이상).
* [Docker](https://download.docker.com/win/stable/Docker%20for%20Windows%20Installer.exe)를 다운로드합니다. 또는 [Docker 웹사이트](https://www.docker.com/products/docker-desktop) 메인 페이지에서 다운로드할 수도 있습니다.

### 설정

* Docker가 [Windows 컨테이너를 사용하도록](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers) 설정되어 있는지 확인
* Powershell 창(관리자 권한)에서:
  * 도구 세트가 추출된 폴더로 이동합니다.
  * docker 네트워크를 설정하고, **LocalMultiplayerAgent**와 통신하기 위한 방화벽 규칙을 추가하고, [Microsoft/PlayFab-Multiplayer](https://hub.docker.com/r/microsoft/playfab-multiplayer/)에서 PlayFab docker 이미지를 가져오는 *Setup.ps1*을 실행합니다. 스크립트를 처음 실행할 때 컨테이너 이미지를 다운로드하는 데 몇 분이 걸릴 수 있습니다.

<Note>
  이 설정을 성공적으로 실행하려면 설치된 타사 백신 프로그램(예: McAfee, Norton 또는 Avira)의 방화벽을 구성해야 할 수 있습니다.
</Note>

### 컨테이너 내에서 게임 서버 실행

* *MultiplayerSettings.json* 파일에서 `RunContainer`를 `true`로 설정합니다.
* 도구 세트가 추출된 폴더(*C:\PlayFabVmAgent*)에서 **Powershell** 창(관리자 권한)을 열고 `LocalMultiplayerAgent.exe`를 실행합니다. 이렇게 하면 컨테이너 내에서 게임 서버가 시작됩니다. 결국 Powershell 창에서 게임 상태 변경 출력이 표시되어야 합니다(위의 GSDK 통합 확인 섹션과 유사).

### 컨테이너 내에서 실행되는 게임 서버에 대한 연결 테스트

**LocalMultiplayerAgent** 출력이 `CurrentGameState - Active`를 인쇄하면 IP 주소 **127.0.0.1**과 *MultiplayerSettings.json* 파일에 지정된 `NodePort`(기본값 **56100**)와 동일한 포트를 사용하여 게임 서버에 연결하세요.

`NumHeartBeatsForActivateResponse` 하트비트 후, **LocalMultiplayerAgent**는 게임 서버가 standby에서 active로 이동하도록 요청합니다. 그런 다음 `NumHeartBeatsForTerminateResponse` 하트비트 후 **LocalMultiplayerAgent**는 게임 서버가 active에서 terminated로 이동하도록 요청합니다. 이 동작은 *MultiplayerSettings.json* 파일의 값을 업데이트하여 조정할 수 있습니다.

### Linux 컨테이너와 함께 LocalMultiplayerAgent 사용

Windows에서 [Docker for Windows](https://docs.docker.com/docker-for-windows/)를 사용하여 컨테이너에서 실행함으로써 LocalMultiplayerAgent를 사용하여 Linux 게임 서버를 디버그할 수 있습니다. Windows에서 Linux 컨테이너를 실행하는 자세한 내용은 [여기](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/linux-containers)에서 확인할 수 있습니다. 요약하자면, 에이전트를 *-lcow* 파라미터로 실행하고 *LocalMultiplayerSettings.json* 파일을 적절히 구성하기만 하면 됩니다.

Windows에서 컨테이너화된 Linux 게임 서버를 실행하려면 다음 단계를 수행해야 합니다:

* GitHub의 [Releases](https://github.com/PlayFab/MpsAgent/releases) 페이지에서 최신 버전의 LocalMultiplayerAgent 다운로드
* [Windows에 Docker Desktop 설치](https://docs.docker.com/docker-for-windows/install/)
* [Linux 컨테이너](https://docs.docker.com/docker-for-windows/#switch-between-windows-and-linux-containers)에서 실행 중인지 확인
* 하드 드라이브 중 하나를 마운트해야 합니다. 지침은 [여기](https://docs.docker.com/docker-for-windows/#file-sharing)에서 찾을 수 있습니다.
* 게임 서버 이미지는 컨테이너 레지스트리에 게시되거나 로컬에서 빌드될 수 있습니다.
* "PlayFab"이라는 Docker 네트워크를 생성하는 `SetupLinuxContainersOnWindows.ps1` Powershell 파일 실행
* *LocalMultiplayerSettings.json* 파일을 적절히 구성합니다. 아래 `MultiplayerSettingsLinuxContainersOnWindowsSample.json`에 포함된 샘플을 확인할 수 있습니다:

```json theme={null}
{
    "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" ]
    }
}
```

<Note>
  몇 가지 참고 사항: 1. 다음을 설정해야 합니다
</Note>

`RunContainer`를 true로. Linux 게임 서버에는 이것이 필요합니다.

<Note>
  2. 다음을 수정합니다
</Note>

`imageDetails`를 게임 서버 docker 이미지 세부 정보로. 이미지는 로컬로 빌드([docker build](https://docs.docker.com/engine/reference/commandline/build/) 명령 사용)되거나 원격 컨테이너 레지스트리에 호스팅될 수 있습니다.

<Note>
  3.
</Note>

`StartGameCommand`와 `AssetDetails`는 선택 사항입니다. Docker 컨테이너를 사용할 때는 일반적으로 이러한 항목을 사용하지 않는데, 모든 게임 자산 + 게임 서버 시작 명령을 해당 [Dockerfile](https://docs.docker.com/engine/reference/builder/)에 패키징할 수 있기 때문입니다.

<Note>
  4. 마지막으로, 하지만 확실히 중요하게, 다음 변수의 대소문자에 주의하세요
</Note>

Linux 컨테이너는 대소문자를 구분하므로 `OutputFolder` 변수. 대소문자가 잘못된 경우 *error while creating mount source path '/host\_mnt/c/output/UnityServerLinux/PlayFabVmAgentOutput/2020-01-30T12-47-09/GameLogs/a94cfbb5-95a4-480f-a4af-749c2d9cf04b': mkdir /host\_mnt/c/output: file exists*와 유사한 Docker 예외가 나타날 수 있습니다.

* 이전 모든 단계를 수행한 후 `LocalMultiplayerAgent.exe -lcow` 명령으로 LocalMultiPlayerAgent를 실행할 수 있습니다(lcow는 *Linux Containers On Windows*의 약자).

### 문제 해결

* 컨테이너 모드에서 게임 서버가 "Container ... exited with exit code 1"과 유사한 오류로 즉시 종료되지만 프로세스 모드에서는 잘 작동하는 경우. 자산 패키지에 필요한 모든 [시스템 DLL](/services/playfab/multiplayer/servers/determining-required-dlls)이 포함되어 있는지 확인하세요.
* 모든 로그는 *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은 이러한 종속성이 있으므로 상대 경로(또는 잘못된 값)는 게임 서버 구성 로딩 오류를 초래할 수 있습니다.

### 알려진 제한 사항

1. 디버깅이 끝난 후 컨테이너가 종료되지 않을 수 있습니다. 이 경우 다음 PowerShell 명령을 관리자 권한으로 실행하세요. 이 명령은 **LocalMultiplayerAgent**에서 시작되지 않은 컨테이너를 포함한 모든 컨테이너를 중지하고 제거합니다.

```powershell theme={null}
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)  
```


## Related topics

- [PlayFab 게임 서버 기본](/ko/services/playfab/multiplayer/servers/basics-of-a-playfab-game-server.md)
- [게임 서버 빌드 작성](/ko/services/playfab/multiplayer/servers/author-a-game-server-build.md)
- [Wrapper 샘플](/ko/services/playfab/multiplayer/servers/wrapper-sample.md)
- [GSDK 프로젝트 테스트 및 디버깅](/ko/services/playfab/multiplayer/servers/server-sdks/unreal-gsdk/third-person-mp-example-project-local-deployment-and-debugging.md)
- [게임 서버를 디버깅하기 위해 직접 연결](/ko/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
