> ## 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 多人遊戲伺服器與 PlayFab 遊戲伺服器 SDK (GSDK) 整合，以及如何驗證整合並進行偵錯。

## 概觀

PlayFab 多人遊戲伺服器需要與 [PlayFab 遊戲伺服器 SDK (GSDK)](/zh-TW/services/playfab/multiplayer/servers/integrating-game-servers-with-gsdk) 整合。此外，遊戲伺服器會在 PlayFab 多人遊戲平台上以容器化應用程式的形式執行。

以容器化應用程式的形式執行，可讓您在與 Azure 中 PlayFab 平台相符的環境中，於本機執行伺服器並進行偵錯。這有助於加快開發反覆項目。本文可協助您確認您的 PlayFab 遊戲伺服器符合平台需求。

PlayFab 本機偵錯工具組包含 [LocalMultiplayerAgent](https://github.com/PlayFab/MpsAgent)，它會向 GSDK 提供模擬回應，並驗證您的遊戲伺服器是否已正確與 GSDK 整合。透過模擬回應，VmAgent 會讓遊戲伺服器循環經歷其在 PlayFab 多人遊戲平台上生命週期中的各種狀態。

您可以設定代理程式，以容器化應用程式的形式執行遊戲伺服器。確認您的遊戲伺服器已封裝所有必要的相依性，並可在 PlayFab 多人遊戲平台上順利執行。LocalMultiplayerAgent 可以搭配 Windows 或 Linux 遊戲伺服器使用。

## 基本設定 - Windows

* 將您的遊戲伺服器與 GSDK 整合並建置。如需詳細資訊，請參閱[將遊戲伺服器與 PlayFab 遊戲伺服器 SDK (GSDK) 整合](/zh-TW/services/playfab/multiplayer/servers/integrating-game-servers-with-gsdk)。
* 將遊戲伺服器及其相依性壓縮為 zip 封存。若要在容器模式中正確執行，zip 封存必須包含容器映像中未包含的任何系統 DLL。如需詳細資訊，請參閱[判斷必要的系統 DLL](/zh-TW/services/playfab/multiplayer/servers/determining-required-dlls)。

<Note>
  避免這個常見錯誤——不要意外地在 zip 中壓縮資料夾*內的*資料夾。壓縮後，請瀏覽 zip 資料夾，並再次確認您的壓縮軟體沒有新增額外的檔案階層。
</Note>

* 下載[本機偵錯工具組](https://github.com/PlayFab/MpsAgent/releases)，並將其解壓縮至您選擇的資料夾 (例如 *C:\PlayFabVmAgent*)。

* 檢查 [LocalMultiplayerAgent MultiplayerSettings.json 產生器](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 路徑不同。容器的 StartGameCommand 路徑是容器或資產資料夾中資源的絕對路徑。處理序的 StartGameCommand 路徑是相對路徑，其工作目錄將是指定的第一個資產。
  * `PortMappingsList` - 這些是遊戲在執行時可用的連接埠。`NodePort` 是在您的工作站上開啟的連接埠，`GamePort.Number` 是您的遊戲伺服器在容器中執行時需要繫結的連接埠。更新 GamePort 區段，使其符合遊戲伺服器接聽用戶端的通訊協定和連接埠。如果您的遊戲伺服器需要多個連接埠，請複製/貼上現有的連接埠設定並遞增 `NodePort`，然後將 `GamePort.Number` 和 `GamePort.Name` 更新為所需的連接埠。以處理序形式執行時，會忽略 `GamePort.Number`，您的處理序應繫結至 NodePort。若要處理這兩種情況，請執行下列其中一項：
    * 將連接埠設定為相同的值
    * 在執行階段檢查 GSDK 設定中索引鍵 `GamePort.Name` 的值，它一律會傳回要繫結的正確連接埠。

* *MultiplayerSettings.json* 檔案中還有其他您可能想要編輯的欄位：
  * `ResourceLimits` (選用) - 如果指定，docker 會限制 CPU/記憶體使用量。警告：如果您的伺服器超過允許的記憶體，它會被終止。只能在容器模式中指定 ResourceLimits。
  * `SessionCookie` (選用) - 作為 [RequestMultiplayerServer API](xref:titleid.playfabapi.com.multiplayer.multiplayerserver.requestmultiplayerserver) 呼叫的一部分傳遞給遊戲伺服器的任何工作階段 Cookie。
  * `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* 檔案中的值來調整此行為。

## 驗證容器化

如果您是容器領域的新手，可以[在此處](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/container-docker-introduction/)查看簡介。

### 先決條件

* 具有 2018 年 4 月 (1803) 更新的 Windows 10 專業版 (或更新版本)。
* 下載 [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 視窗中 (以系統管理員身分)：
  * 瀏覽至解壓縮工具組的資料夾。
  * 執行 *Setup.ps1*，它會設定 docker 網路、新增防火牆規則以便與 **LocalMultiplayerAgent** 通訊，並從 [Microsoft/PlayFab-Multiplayer](https://hub.docker.com/r/microsoft/playfab-multiplayer/) 提取 PlayFab docker 映像。請注意，第一次執行指令碼時，可能需要幾分鐘的時間來下載容器映像。

<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** 會要求遊戲伺服器從待命移至作用中。接著在 `NumHeartBeatsForTerminateResponse` 次活動訊號後，**LocalMultiplayerAgent** 會要求遊戲伺服器從作用中移至已終止。您可以更新 *MultiplayerSettings.json* 檔案中的值來調整此行為。

### 搭配 Linux 容器使用 LocalMultiplayerAgent

您可以使用 [Windows 版 Docker](https://docs.docker.com/docker-for-windows/)，在 Windows 的容器上執行您的 Linux 遊戲伺服器，以使用 LocalMultiplayerAgent 對其進行偵錯。您可以[在此處](https://learn.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/linux-containers)查看有關在 Windows 上執行 Linux 容器的更多資訊。基本上，您只需使用 *-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)找到指示
* 您的遊戲伺服器映像可以發佈在容器登錄上，也可以在本機建置。
* 執行 `SetupLinuxContainersOnWindows.ps1` Powershell 檔案，它會建立名為 "PlayFab" 的 Docker 網路
* 正確設定 *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. 使用您的遊戲伺服器 docker 映像詳細資料修改
</Note>

`imageDetails`。映像可以在本機建置 (使用 [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>

`OutputFolder` 變數的大小寫，因為 Linux 容器會區分大小寫。如果大小寫錯誤，您可能會看到類似以下的 Docker 例外狀況：*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*

* 執行所有先前的步驟後，您就可以使用命令 `LocalMultiplayerAgent.exe -lcow` 執行 LocalMultiPlayerAgent (lcow 代表 *Linux Containers On Windows*)

### 疑難排解

* 在容器模式中，如果您的遊戲伺服器立即結束並出現類似 "Container ... exited with exit code 1" 的錯誤，但在處理序模式中運作正常，請確定您已在資產套件中包含所有必要的[系統 DLL](/zh-TW/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 遊戲伺服器的基本概念](/zh-TW/services/playfab/multiplayer/servers/basics-of-a-playfab-game-server.md)
- [Wrapper 範例](/zh-TW/services/playfab/multiplayer/servers/wrapper-sample.md)
- [直接連線以對遊戲伺服器進行偵錯](/zh-TW/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
- [使用 LocalMultiplayerAgent 對處理序型遊戲伺服器進行偵錯](/zh-TW/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-process-based-gameserver.md)
- [使用 LocalMultiplayerAgent 對容器遊戲伺服器進行偵錯](/zh-TW/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-container-gameserver.md)
