> ## 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.

# LocalMultiplayerAgent로 컨테이너 게임 서버 디버깅

> PlayFab 멀티플레이어 게임 서버를 Linux 또는 Windows 컨테이너로 패키징하고 컨테이너 모드에서 LocalMultiplayerAgent 아래에서 실행하여 로컬로 디버깅합니다.

# 컨테이너 모드에서 LocalMultiplayerAgent를 사용해 게임 서버를 실행하는 방법

이 튜토리얼에서는 다음을 설명합니다:

* Wrapper 샘플을 사용해 \[Linux/Windows] 컨테이너 빌드 생성
* MultiplayerSettings.json 구성
* Docker 설정
* LocalMultiplayerAgent 실행
* 게임 연결 테스트

## \[Linux/Windows] 컨테이너 빌드 생성

컨테이너에 익숙하지 않은 경우 [컨테이너 및 Docker 소개](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/container-docker-introduction/)를 참조하세요.

기존 샘플을 Windows 또는 Linux 컨테이너로 패키징하는 방법을 알아봅니다. 플랫폼(Windows/Linux 기반 컨테이너)에 따라 서로 다른 설정을 구성해야 합니다. 여기서는 Wrapper 샘플을 사용하여 세부 사항을 살펴봅니다.

### Linux 컨테이너 빌드

Linux 컨테이너를 사용하여 Linux 빌드에서 wrapper와 fakegame 실행 파일을 실행할 수 있습니다. 이 경우 Linux 빌드를 만들어야 합니다.
Wrapper Linux 빌드를 만드는 방법을 알아보려면 [Linux 컨테이너 이미지를 만드는 방법](/services/playfab/multiplayer/servers/wrapper-sample#create-and-upload-linux-container-image-for-linux-servers-only)을 참조하세요.

### Windows 컨테이너 빌드

LMA가 Windows 컨테이너 빌드를 생성합니다. 설정을 올바르게 구성하기만 하면 됩니다 (나중에 Windows 컨테이너 설정 구성 방법을 확인하세요).

## MultiplayerSettings.json 구성

LMA 툴셋을 압축 해제한 폴더로 이동하여 MultiplayerSettings.json 파일을 엽니다. 이 파일은 MPS의 빌드를 시뮬레이션하는 빌드 구성 모의 파일입니다.

[LMA MultiplayerSettings.json Generator](https://github.com/PlayFab/MpsAgent/tree/main/LocalMultiplayerAgent/SettingsJsonGenerator)를 사용하여 json을 채울 수도 있습니다. Generator는 옵션을 기반으로 json을 생성하는 간단한 웹 페이지입니다. Generator는 LocalMultiplayerAgent/SettingsJsonGenerator 아래에서 찾을 수 있습니다.

다음은 Wrapper 샘플을 `Linux Container`로 실행하기 위한 MultiplayerSettings.Json의 예입니다.

```json theme={null}
{
    "RunContainer": true, // Set RunContainer to true if you are running LMA in Container mode.
    "OutputFolder": "C:\\output\\LMAContainer", // Path where config files and logs will be generated from LMA at each run
    "NumHeartBeatsForActivateResponse": 10,
    "NumHeartBeatsForTerminateResponse": 60,
    "TitleId": "", // default value
    "BuildId": "00000000-0000-0000-0000-000000000000", // default value
    "Region": "59F84", // default value
    "AgentListeningPort": 56001, // default value
    "ContainerStartParameters": {
        /// replace ImageDetails fields to your own images saved on ACR.
        "ImageDetails": {
            "Registry": "mydockerregistry.io",
            "ImageName": "wrapper",
            "ImageTag": "0.1",
            "Username": "",
            "Password": ""
        }
    },
    "PortMappingsList": [
        [
            {
                "NodePort": 56100,
                "GamePort": {
                    "Name": "game_port", 
                    // The same value of GamePort Name should be also defined in the Wrapper so Wrapper can get a port information while it's running.
                    "Number": 80,
                    "Protocol": "TCP"
                }
            }
        ]
    ],
}
```

`Windows Container`의 경우 컨테이너를 빌드할 필요가 없습니다. LMA가 게임 서버를 Windows 컨테이너로 패키징합니다. `ImageDetails` 필드에 Windows 컨테이너 기본 이미지를 지정하고, 게임 자산이 워크스테이션에 있는 위치로 `LocalFilePath`를 설정하기만 하면 됩니다.

```json theme={null}
"AssetDetails": [
    {
      "MountPath": "C:\\Assets",  
      // Mount Path should be "C:\\Assets" for Windows Container. 
      "LocalFilePath": "D:\\gameassets.zip" 
      // where your game server is located as an archive format.
    }
  ]

 "ContainerStartParameters": {
    "StartGameCommand": "C:\\Assets\\wrapper.exe -g C:\\Assets\\fakegame.exe arg1 arg2", 
    // Your game assets will be extracted under C:\\Assets (default mount path for Windows Container) and LMA will run your game server with StartGameCommand argument. 
     // Make sure the StartGameCommand provided above is an example of the Wrapper sample. 
    "ImageDetails": {
      "Registry": "mcr.microsoft.com",
      "ImageName": "playfab/multiplayer",
      "ImageTag": "wsc-10.0.17763.973.1",
      "Username": "", 
      "Password": ""
      // username and password are not required to use MCR image.
    }
    // LMA will package an existing game sample (path defined in LocalFilePath) as a Windows container.
 }

```

컨테이너 모드에서 LMA를 실행하려면 MultiplayerSettings.json의 다음 필드를 올바르게 업데이트해야 합니다.

* `LocalFilePath` - 이전에 만든 게임 서버 자산 zip 파일의 워크스테이션 로컬 전체 경로입니다. 예: D:\gameassets.zip (JSON 형식을 위해 백슬래시는 이스케이프해야 함). 이 필드는 LMA가 게임 자산을 찾아 컨테이너에 패키징해야 하므로 Windows 컨테이너에 필요합니다.

* `PortMappingsList` - 게임 실행 중 사용할 수 있는 포트입니다.

  * `NodePort`는 워크스테이션에서 열리는 포트로 GamePort에 매핑됩니다.
  * `GamePort.Number`는 컨테이너에서 실행될 때 게임 서버가 바인딩해야 하는 포트입니다. 예를 들어 여기서는 fakegame.exe가 수신 대기할 포트 번호를 80으로 설정합니다.
  * `GamePort.Name`을 게임 서버에 정의된 것과 동일한 값으로 설정합니다. 런타임 시 GamePort.Name 키로 GSDK 구성에서 값을 확인할 수 있습니다.
  * `GamePort.Protocol` - 프로토콜 유형 지정: TCP 또는 UDP

  게임 서버가 클라이언트를 수신 대기하는 프로토콜 및 포트와 일치하도록 GamePort 섹션을 업데이트합니다. 여러 포트를 추가할 수 있습니다.

* `ForcePullFromAcrOnLinuxContainersOnWindows` - Docker Registry에서 Linux 컨테이너 이미지를 가져오고 로컬 레지스트리에서 가져오는 것을 방지하려면 true로 설정합니다. 대부분의 경우 false로 설정하는 것이 좋습니다.

* `ContainerStartParameters.ImageDetails` - 게임 서버 이미지는 컨테이너 레지스트리에 게시되거나 로컬로 빌드될 수 있습니다. Docker Registry(예: Azure Registry)에서 Linux 컨테이너 이미지를 가져오려면 username과 password 값을 설정하고 `ForcePullFromAcrOnLinuxContainersOnWindows`를 true로 설정해야 합니다. Windows 컨테이너의 경우 username과 password가 필요하지 않습니다.

* `OutputFolder` - 출력 및 구성 파일이 생성되는 드라이브 또는 폴더의 경로입니다. 이 경로 아래에 게임 서버가 압축 해제되므로 사용 가능한 공간이 충분한지 확인하세요. 지정하지 않으면 에이전트 폴더가 사용됩니다.

* `AgentListeningPort` - LMA가 게임 서버와 통신하는 포트입니다. 열려 있는 모든 포트가 작동하며 56001이 기본값입니다. 다른 프로세스가 56001에 바인딩되어 있는 경우 이 값을 변경하거나 포트 56001의 다른 프로세스를 종료해야 합니다.

* `ResourceLimits` (선택 사항) - 지정된 경우 docker가 CPU/메모리 사용량을 제한합니다. 경고: 서버가 허용된 메모리를 초과하면 종료됩니다. ResourceLimits는 컨테이너 모드에서만 지정할 수 있습니다.

* `SessionCookie` (선택 사항) - RequestMultiplayerServer API 호출의 일부로 게임 서버에 전달되는 세션 쿠키입니다. MPS의 실제 시나리오에서 연결이 설정된 후 서버는 SessionCookie에서 해당 리소스를 로드하도록 클라이언트에 알립니다.

## Docker 설정

"PlayFab"이라는 docker 네트워크를 설정하고 LocalMultiplayerAgent와 통신하기 위한 방화벽 규칙을 추가하는 PowerShell 스크립트를 실행하세요.

* Linux 컨테이너의 경우 `SetupLinuxContainersOnWindows.ps1`을 실행합니다.\
  Windows 컨테이너의 경우 `Setup.ps1`을 실행합니다. Microsoft/PlayFab-Multiplayer에서 PlayFab docker 이미지를 가져옵니다.\
  스크립트가 처음 실행될 때 컨테이너 이미지를 다운로드하는 데 몇 분 정도 걸릴 수 있습니다.
  > 이 설정을 성공적으로 실행하려면 설치된 타사 안티바이러스 프로그램의 방화벽을 구성해야 할 수도 있습니다.

Windows와 Linux 컨테이너 간에 올바른 docker 데몬을 대상으로 지정하는 방법을 알아보려면 [Docker를 Windows/Linux 컨테이너를 사용하도록 전환하는 방법](https://docs.docker.com/desktop/windows/#switch-between-windows-and-linux-containers)을 참조하세요.

## LocalMultiplayerAgent 실행

* PowerShell 창에서:\
  LocalMultiplayerAgent.exe가 포함된 LMA 아래 디렉터리로 이동합니다.

* Windows 컨테이너의 경우 `LocalMultiplayerAgent.exe`를 실행합니다.\
  Linux 컨테이너의 경우 `LocalMultiplayerAgent.exe -lcow`를 실행합니다.\
  (lcow는 Linux Containers On Windows를 의미합니다)

  이 시점에서 LMA는 http 리스너를 설정하고 컨테이너를 실행합니다.
  `docker ps` 명령을 실행하여 컴퓨터에서 실행 중인 컨테이너를 볼 수 있습니다.

LMA는 게임 서버와 통합된 GSDK로부터 하트비트를 기다립니다.
GSDK가 올바르게 통합된 경우 LMA는 다음 순서로 출력을 표시합니다:

1. `CurrentGameState - Initializing`\
   (게임 서버가 GSDK::ReadyForPlayers를 직접 호출하고 GSDK::Start를 호출하지 않는 경우 표시되지 않을 수 있습니다.)
2. `CurrentGameState - StandingBy`
3. `CurrentGameState - Active`
4. `CurrentGameState - Terminating`

게임 서버 상태에 대해 자세히 알아보려면 [PlayFab Multiplayer Server의 게임 서버 수명 주기란 무엇인가요](/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle)를 참조하세요.

종료 콜백이 올바르게 설정된 경우 상태가 terminating으로 설정된 직후에 게임 서버가 종료됩니다.
PlayFab 플랫폼에서 정상적으로 종료되지 않는 상황을 피하기 위해 게임 서버가 종료되는지 확인하는 것이 중요합니다.

LMA도 게임과 함께 종료되어야 합니다.

## 게임 연결 테스트

LMA가 **CurrentGameState - Active**를 출력하면 IP 주소 127.0.0.1과 게임 서버가 수신 대기 중인 포트 NodePort를 사용하여 게임 서버에 연결할 수 있습니다.

Wrapper 샘플을 사용하는 경우 브라우저에 [http://127.0.0.1:56100/Hello](http://127.0.0.1:56100/Hello) 주소를 입력하여 GET 요청을 테스트할 수 있습니다.
자세한 내용은 Wrapper 샘플을 확인하세요.

또한 MultiplayerSettings.json의 **NumHeartBeatsForActivateResponse** 및 **NumHeartBeatsForTerminateResponse** 값을 업데이트하여 stand-by/active 상태의 지속 시간을 조정할 수도 있습니다.

### 문제 해결

* 컨테이너 모드에서 게임 서버가 "Container ... exited with exit code 1"과 유사한 오류로 즉시 종료되지만 프로세스 모드에서는 정상적으로 작동하는 경우, 자산 패키지에 필요한 모든 [시스템 DLL](/services/playfab/multiplayer/servers/determining-required-dlls)이 포함되어 있는지 확인하세요.
* 모든 로그는 *MultiplayerSettings.json* 파일에 지정된 `OutputFolder` 아래에 있습니다. **LocalMultiplayerAgent**는 시작될 때마다 타임스탬프를 폴더 이름으로 하는 새 폴더를 생성합니다. GSDK를 통해 발생한 모든 게임 서버 로그는 GameLogs 폴더 내에 위치합니다.\
  게임 서버가 컨테이너에서 실행 중이라면 뒤져야 할 디렉터리 계층이 하나 더 있을 수 있습니다.
* GSDK는 디버그 로그를 `OutputFolder` 아래의 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 is 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*을 다시 실행해 보세요.

### 알려진 제한 사항

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

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


## Related topics

- [게임 서버 로컬 디버깅 및 PlayFab과의 통합](/ko/services/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab.md)
- [LocalMultiplayerAgent를 사용하여 프로세스 기반 게임 서버 디버깅](/ko/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-process-based-gameserver.md)
- [게임 서버를 디버깅하기 위해 직접 연결](/ko/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
- [LocalMultiplayerAgent 개요](/ko/services/playfab/multiplayer/servers/LocalMultiplayerAgent/local-multiplayer-agent-overview.md)
- [GSDK 프로젝트 테스트 및 디버깅](/ko/services/playfab/multiplayer/servers/server-sdks/unreal-gsdk/third-person-mp-example-project-local-deployment-and-debugging.md)
