> ## 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。你可以在 LocalMultiplayerAgent/SettingsJsonGenerator 下找到 Generator。

下面是将 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.
 }

```

请确保正确更新 MultiplayerSettings.json 中的以下字段,以在容器模式下运行 LMA。

* `LocalFilePath` — 之前创建的游戏服务器资产 zip 文件的完整本地路径(在你的工作站上),例如:D:\gameassets.zip(注意反斜杠需要为 JSON 格式进行转义)。此字段对于 Windows 容器是必需的,因为 LMA 需要定位你的游戏资产,然后将其打包到容器中。

* `PortMappingsList` — 这些是游戏运行时可用的端口。

  * `NodePort` 是在你的工作站上打开的端口,并将映射到 GamePort。
  * `GamePort.Number` 是你的游戏服务器在容器中运行时需要绑定的端口。例如,此处我们将端口号设为 80,即 fakegame.exe 将监听该端口。
  * 将 `GamePort.Name` 设为与游戏服务器中定义的相同值。你可以在运行时通过键 GamePort.Name 检查 GSDK 配置来获取该值。
  * `GamePort.Protocol` — 指定协议类型:TCP 或 UDP

  更新 GamePort 部分以匹配你的游戏服务器监听客户端所使用的协议和端口。你可以添加多个端口。

* `ForcePullFromAcrOnLinuxContainersOnWindows` — 当你希望从 Docker 注册表拉取 Linux 容器映像并避免从本地注册表拉取时,设置为 true。在大多数情况下,你会希望将其设置为 false。

* `ContainerStartParameters.ImageDetails` — 你的游戏服务器映像可以发布到容器注册表,或者可以在本地生成。如果你希望从 Docker 注册表(例如 Azure Registry)拉取 Linux 容器映像,则需要为 username 和 password 设置值,并将 `ForcePullFromAcrOnLinuxContainersOnWindows` 设为 true。对于 Windows 容器,不需要 username 和 password。

* `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 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** 的值,以调整 standing-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"。可能是已有容器正在使用指定的端口运行。` 这可能发生在 **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-CN/services/playfab/multiplayer/servers/LocalMultiplayerAgent/run-process-based-gameserver.md)
- [LocalMultiplayerAgent 概述](/zh-CN/services/playfab/multiplayer/servers/LocalMultiplayerAgent/local-multiplayer-agent-overview.md)
- [在本地调试游戏服务器以及与 PlayFab 的集成](/zh-CN/services/playfab/multiplayer/servers/locally-debugging-game-servers-and-integration-with-playfab.md)
- [直接连接以调试游戏服务器](/zh-CN/services/playfab/multiplayer/servers/directly-debugging-game-servers.md)
- [创作游戏服务器生成](/zh-CN/services/playfab/multiplayer/servers/author-a-game-server-build.md)
