> ## 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 容器映像](/zh-TW/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 產生器](https://github.com/PlayFab/MpsAgent/tree/main/LocalMultiplayerAgent/SettingsJsonGenerator)填入 json。產生器是一個簡單的網頁，會根據您的選項建立 json。您可以在 LocalMultiplayerAgent/SettingsJsonGenerator 下找到產生器。

以下是以 `Linux Container` 形式執行 Wrapper 範例的 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.
 }

```

請務必在 MultiplayerSettings.json 中正確更新下列欄位，以容器模式執行 LMA。

* `LocalFilePath` - 先前建立之遊戲伺服器資產 zip 檔案的完整本機路徑 (在您的工作站上)，例如：D:\gameassets.zip (請注意，反斜線需要針對 JSON 格式進行逸出)。Windows 容器需要此欄位，因為 LMA 需要找到您的遊戲資產，然後將其封裝至容器中。

* `PortMappingsList` - 這些是遊戲在執行時可用的連接埠。

  * `NodePort` 是在您的工作站上開啟並將對應至 GamePort 的連接埠。
  * `GamePort.Number` 是您的遊戲伺服器在容器中執行時需要繫結的連接埠。例如，這裡我們將連接埠號碼設定為 80，fakegame.exe 將接聽此連接埠。
  * 將 `GamePort.Name` 設定為與遊戲伺服器中定義的相同值。您可以在執行階段檢查 GSDK 設定中索引鍵 GamePort.Name 的值。
  * `GamePort.Protocol` - 指定通訊協定類型：TCP 或 UDP

  更新 GamePort 區段，使其符合遊戲伺服器接聽用戶端的通訊協定和連接埠。您可以新增多個連接埠。

* `ForcePullFromAcrOnLinuxContainersOnWindows` - 當您想要從 Docker 登錄提取 Linux 容器映像並避免從本機登錄提取時，請設定為 true。在大多數情況下，您會希望將此設定為 false。

* `ContainerStartParameters.ImageDetails` - 您的遊戲伺服器映像可以發佈在容器登錄上，也可以在本機建置。如果您想要從 Docker 登錄 (例如 Azure 登錄) 提取 Linux 容器映像，則需要設定使用者名稱和密碼的值，並將 `ForcePullFromAcrOnLinuxContainersOnWindows` 設定為 true。對於 Windows 容器，不需要使用者名稱和密碼。

* `OutputFolder` - 產生輸出和設定檔之磁碟機或資料夾的路徑。由於遊戲伺服器將解壓縮至此路徑下，請確定有足夠的可用空間。如果未指定，則會使用代理程式資料夾。

* `AgentListeningPort` - 這是 LMA 與遊戲伺服器通訊的連接埠。任何開放的連接埠都可以使用，預設值為 56001。如果您有其他處理序繫結至 56001，則必須變更此值或終止連接埠 56001 上的其他處理序。

* `ResourceLimits` (選用) - 如果指定，docker 會限制 CPU/記憶體使用量。警告：如果您的伺服器超過允許的記憶體，它會被終止。只能在容器模式中指定 ResourceLimits。

* `SessionCookie` (選用) - 作為 RequestMultiplayerServer API 呼叫的一部分傳遞給遊戲伺服器的任何工作階段 Cookie。在 MPS 上的實際案例中，建立連線後，伺服器會通知用戶端從 SessionCookie 載入對應的資源。

## 設定 Docker

執行 PowerShell 指令碼以設定名為 "PlayFab" 的 docker 網路，並新增防火牆規則以便與 LocalMultiplayerAgent 通訊。

* 對於 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 視窗中：\
  瀏覽至 LMA 下包含 LocalMultiplayerAgent.exe 的目錄。

* 對於 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 多人遊戲伺服器的遊戲伺服器生命週期是什麼](/zh-TW/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle)。

如果關閉回呼設定正確，您的遊戲伺服器會在狀態設定為終止後很快結束。
請務必確認遊戲伺服器會結束，以避免在 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** 的值，以調整待命/作用中狀態的持續時間。

### 疑難排解

* 在容器模式中，如果您的遊戲伺服器立即結束並出現類似 "Container ... exited with exit code 1" 的錯誤，但在處理序模式中運作正常，請確定您已在資產套件中包含所有必要的[系統 DLL](/zh-TW/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

- [使用 LocalMultiplayerAgent 對處理序型遊戲伺服器進行偵錯](/zh-TW/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-process-based-gameserver.md)
- [在本機對遊戲伺服器進行偵錯以及與 PlayFab 整合](/zh-TW/services/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab.md)
- [LocalMultiplayerAgent 概觀](/zh-TW/services/playfab/multiplayer/servers/LocalMultiplayerAgent/local-multiplayer-agent-overview.md)
- [直接連線以對遊戲伺服器進行偵錯](/zh-TW/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
- [GSDK 專案測試和偵錯](/zh-TW/services/playfab/multiplayer/servers/server-sdks/unreal-gsdk/third-person-mp-example-project-local-deployment-and-debugging.md)
