如何在容器模式下使用 LocalMultiplayerAgent 运行游戏服务器

本教程介绍如何:

  • 使用包装器示例创建 [Linux/Windows] 容器生成
  • 配置 MultiplayerSettings.json
  • Docker 设置
  • 运行 LocalMultiplayerAgent
  • 测试游戏连接

创建 [Linux/Windows] 容器生成

如果不熟悉容器,请参阅容器和 Docker 简介

将了解如何将现有示例打包为 Windows 或 Linux 容器。 需要为不同的平台(基于 Windows/Linux 的容器)配置不同的设置。 在这里,我们将使用包装器示例并详细介绍。

Linux 容器生成

可以使用 Linux 容器在 Linux 生成上运行包装器和 fakegame 可执行文件。 在这种情况下,需要创建 Linux 生成。 要了解如何创建包装器 Linux 生成,请参阅如何创建 Linux 容器映像

Windows 容器生成

LMA 将创建 Windows 容器生成。 只需要正确配置设置(稍后查看如何为 Windows 容器配置设置)

配置 MultiplayerSettings.json

导航到提取 LMA 工具集的文件夹,然后打开 MultiplayerSettings.json 文件。 此文件是生成配置模拟文件,用于模拟 MPS 上的生成。

还可以使用 LMA MultiplayerSettings.json 生成器填充 json。 生成器是简单的网页,可基于选项创建 json。 可以在 LocalMultiplayerAgent/SettingsJsonGenerator 下找到生成器。

以下是 MultiplayerSettings.Json 的示例,用于将包装器示例作为 Linux Container 运行。

{
    "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 设置为游戏资产在工作站上的位置。

"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 Registry 中提取 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 容器

运行 LocalMultiplayerAgent

  • 在 PowerShell 窗口中:
    导航到 LMA 下包含 LocalMultiplayerAgent.exe 的目录。

  • 针对 Windows 容器运行 LocalMultiplayerAgent.exe
    针对 Linux 容器运行 LocalMultiplayerAgent.exe -lcow
    (lcow 代表 Windows 上的 Linux 容器)

    此时,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 多人服务器的游戏服务器生命周期

如果已正确设置关闭回调,则游戏服务器会在状态设置为终止后立即退出。 请务必核实游戏服务器已退出,以避免 PlayFab 平台上出现意外关闭。

LAM 还应与游戏一起终止。

测试与游戏的连接

一旦 LMA 打印出 CurrentGameState - Active,就可以使用 IP 地址 127.0.0.1 和游戏服务器进行侦听的端口 NodePort 连接到游戏服务器。

如果使用包装器示例,可以通过在浏览器中输入地址 http://127.0.0.1:56100/Hello 来测试 GET 请求。 有关更多详细信息,请检查包装器示例。

还可以更新 MultiplayerSettings.json 中的 NumHeartBeatsForActivateResponseNumHeartBeatsForTerminateResponse 的值,以调整备用/活动状态的持续时间。

故障排除

  • 在容器模式下,如果游戏服务器立即退出,并出现类似于「容器...退出代码 1」,但它在进程模式下正常工作,请确保已将所有所需的系统 DLL 包含在资产包中。
  • 所有日志都位于 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 启动的容器。
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)