在本地调试游戏服务器以及与 PlayFab 的集成

概述

PlayFab 多人游戏服务器需要与 PlayFab Game Server SDK (GSDK) 集成。 此外,游戏服务器在 PlayFab 多人游戏平台上作为容器化应用程序运行。

通过作为容器化应用程序运行它们,可以采用与 Azure 中 PlayFab 平台的环境相匹配的环境,在本地运行和调试服务器。 这有助于实现更快的开发迭代。 本文可帮助验证 PlayFab 游戏服务器是否符合平台要求。

PlayFab 本地调试工具集包含 LocalMultiplayerAgent ,它提供对 GSDK 的模拟响应,并验证游戏服务器是否正确集成到 GSDK。 借助模拟响应,VmAgent 可使游戏服务器经历在 PlayFab 多人游戏平台上的生命周期内的各种状态。

可以将代理配置为将游戏服务器作为容器化应用程序运行。 验证游戏服务器是否已打包所有必需的依赖项,并在 PlayFab 多人游戏平台上顺利运行。 LocalMultiplayerAgent 可以与 Windows 或 Linux 游戏服务器配合使用。

基本设置 - Windows

  • 将游戏服务器与 GSDK 集成并进行生成。 有关详细信息,请参阅 将游戏服务器与Playfab游戏服务器SDK(GSDK)集成

  • 将游戏服务器及其依赖项压缩到 zip 存档。 若要在容器模式下正常运行,zip 存档必须包含容器映像中未包含的任何系统 DLL。 有关详细信息,请参阅确定所需的系统 DLL

    注意

    避免此常见错误 - 不要无意中将文件夹压缩到 zip 中的文件夹。 压缩之后,浏览 zip 文件夹,仔细检查压缩软件是否未添加额外一层文件结构。

  • 下载 本地调试工具集 并将其解压缩到所选文件夹(如 C:\PlayFabVmAgent)。

  • 检查 LocalMultiplayerAgent MultiplayerSettings.json Generator json 文件时,请阅读以下选项的详细信息。

  • 导航到提取的文件夹的位置,并在文本编辑器中打开 MultiplayerSettings.json 文件(如 Visual Studio Code)。 更新以下属性:

    • LocalFilePath - 游戏服务器资产 zip 文件的完整本地路径(位于工作站上),例如 D:\\MyAmazingGame\\asset.zip(请注意,需要转义反斜杠才能进行 JSON 格式设置)。
    • StartGameCommand - 容器内游戏服务器可执行文件的完整路径。 例如,如果可执行文件的名称 mygame.exe,则示例路径将为 C:\\Assets\\mygame.exe。 对于进程和容器,StartGameCommand 的路径不同。 容器的 StartGameCommand 路径是容器或资产文件夹中资源的绝对路径。 进程的 StartGameCommand 路径是一个相对路径,其中工作目录将是指定的第一个资产。
    • PortMappingsList - 这些是可供游戏运行时使用的端口。 NodePort 是在工作站上打开的端口,GamePort.Number 是游戏服务器在容器中运行时需要绑定到的端口。 更新 GamePort 部分,以匹配游戏服务器侦听客户端时所使用的协议和端口。 如果游戏服务器需要多个端口,请复制/粘贴现有端口配置并递增 NodePort 然后更新 GamePort.NumberGamePort.Name 到所需的端口。 当作为进程运行时, GamePort.Number 将被忽略,则进程应绑定到 NodePort。 若要处理这两种情况,请执行下列操作之一:
      • 将端口设置为相同的值
      • 在运行时检查 GSDK 配置中是否具有键 GamePort.Name 的值始终返回要绑定的正确端口。
  • MultiplayerSettings.json文件中有其他字段,可能需要编辑:

    • ResourceLimits(可选)- 如果指定,Docker 会限制 CPU/内存使用率。 警告: 如果服务器超出允许的内存,则会将其终止。 只能在容器模式下指定 ResourceLimits。
    • SessionCookie(可选)- 作为 RequestMultiplayerServer API 调用的一部分传递给游戏服务器的任何会话 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 文件中的值来优化此行为。

验证容器化

如果你不熟悉容器领域,可以在此处查看简介。

先决条件

  • 带有 2018 年 4 月 (1803) 更新的 Windows 10 专业版(或更改版本)。
  • 下载 Docker。 或者,可以从 Docker 网站的主页下载它。

设置

  • 确保 Docker 设置为使用 Windows 容器
  • 在 Powershell 窗口中(以管理员身份):
    • 导航到提取工具集的文件夹。
    • 运行 Setup.ps1,用于设置 docker 网络、添加防火墙规则以与 LocalMultiplayerAgent 通信,并从 Microsoft/PlayFab-Multiplayer 中下拉 PlayFab docker 映像。 请注意,首次运行脚本时,可能需要几分钟时间才能下载容器映像。

      注意

      若要成功运行此设置,必须对已安装的任何第三方防病毒程序(如 McAfee、Norton 或 Avira)的防火墙进行配置。

在容器中运行游戏服务器

  • MultiplayerSettings.json 文件中,将 RunContainer 设置为 true
  • 在提取工具集的文件夹(C:\PlayFabVmAgent)中打开Powershell窗口(以管理员身份)并运行LocalMultiplayerAgent.exe。 这将启动容器中的游戏服务器。 最后,可以在 Powershell 窗口中看到游戏状态更改输出(与上面“验证 GSDK 集成”一节中一样)。

测试与在容器中运行的游戏服务器的连接

LocalMultiplayerAgent输出打印CurrentGameState - Active时,请使用 MultiplayerSettings.json 文件中指定的 IP 地址127.0.0.1和等于NodePort默认情况下为 56100)的端口连接到游戏服务器。

NumHeartBeatsForActivateResponse检测信号后,LocalMultiplayerAgent请求游戏服务器从待机状态移动到活动状态。 然后, NumHeartBeatsForTerminateResponse 检测信号 LocalMultiplayerAgent 请求游戏服务器从活动状态移动到终止状态。 可以通过更新 MultiplayerSettings.json 文件中的值来优化此行为。

将 LocalMultiplayerAgent 与 Linux 容器配合使用

你可以使用 LocalMultiplayerAgent 在 Windows 中的容器上使用 用于 Windows 的 Docker运行它来调试 Linux 游戏服务器。 有关在 Windows 上运行 Linux 容器的详细信息,请参阅此处。 实质上,只需使用 -lcow 参数运行代理,并正确配置 LocalMultiplayerSettings.json 文件。

若要在 Windows 上运行容器化 Linux 游戏服务器,需要执行以下步骤:

  • 从 GitHub 上的" 版本" 页下载最新版本的 LocalMultiplayerAgent
  • 在 Windows 上安装 Docker Desktop
  • 确保它在 Linux 容器上运行
  • 应装载其中一个硬盘驱动器,可在此处找到说明
  • 游戏服务器映像可以发布在容器注册表上,也可以在本地生成。
  • 运行 SetupLinuxContainersOnWindows.ps1 Powershell 文件,该文件创建名为“PlayFab”的 Docker 网络
  • 正确配置 LocalMultiplayerSettings.json 文件。 下面可以看到一个示例,包含在 MultiplayerSettingsLinuxContainersOnWindowsSample.json中:
{
    "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" ]
    }
}

一些备注:

  1. 必须将 RunContainer 设置为 true。 这是 Linux 游戏服务器所必需的。
  2. 使用游戏服务器 docker 映像详细信息修改 imageDetails。 映像可以本地生成(使用 docker build 命令)或托管在远程容器注册表中。
  3. StartGameCommandAssetDetails 是可选的。 使用 Docker 容器时通常不会使用它们,因为所有游戏资产 + 启动游戏服务器命令都可以打包在相应的 Dockerfile
  4. 最后,但并非最不重要的一点是,请注意 OutputFolder 变量的大小写,因为 Linux 容器区分大小写。 如果大小写错误,您可能会在创建挂载源路径时看到类似于错误的 Docker 异常 '/host_mnt/c/output/UnityServerLinux/PlayFabVmAgentOutput/2020-01-30T12-47-09/GameLogs/a94cfbb5-95a4-480f-a4af -749c2d9cf04b': mkdir /host_mnt/c/output: 文件存在
  • 执行上述所有步骤后,可以使用命令LocalMultiplayerAgent.exe -lcow运行 LocalMultiPlayerAgent(lcow 代表Windows上的Linux 容器

故障排除

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