在本地调试游戏服务器以及与 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.Number
并GamePort.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 文件中的值来优化此行为。
验证容器化
如果你不熟悉容器领域,可以在此处查看简介。
先决条件
设置
- 确保 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" ]
}
}
一些备注:
- 必须将
RunContainer
设置为 true。 这是 Linux 游戏服务器所必需的。- 使用游戏服务器 docker 映像详细信息修改
imageDetails
。 映像可以本地生成(使用 docker build 命令)或托管在远程容器注册表中。StartGameCommand
和AssetDetails
是可选的。 使用 Docker 容器时通常不会使用它们,因为所有游戏资产 + 启动游戏服务器命令都可以打包在相应的 Dockerfile- 最后,但并非最不重要的一点是,请注意
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 具有此类依赖项,因此此处的相对路径(或不正确的值)可能会导致游戏服务器配置加载错误。
已知限制
- 容器可能不会在调试结束时终止。 如果发生这种情况,请以管理员身份运行以下 PowerShell 命令。 这些命令停止并删除所有容器,包括那些不是由localMultiplayerAgent启动的。
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)