在多人联机项目里,服务器托管往往比游戏玩法本身更容易卡住。这里以 Gorebox 这类需要实时同步状态的项目为例,讲清楚如何用 Photon 完成服务器托管。很多团队在本地跑通功能后,一进入正式托管阶段就会遇到各种问题,比如客户端连不上、服务端收不到玩家状态、日志里没有任何输出等。这篇文章会把托管流程拆成“选型、配置、接入、验证、排错、加固”几个阶段,每个阶段都给出具体的配置和检查方法,适合已经了解基本游戏开发、正准备把自己的 Gorebox 服务端发布到 Photon 的开发者阅读。
学习环境里跑通 Photon 托管并不难,难的是进入生产环境后,配置变更为什么没有生效、连接超时该看哪一层日志、不同客户端为什么表现不一致。因此整篇文章不会只停留在“点击发布”的层面,而是会把 Photon 托管服务器时的核心配置、客户端接入要点、日志和运维手段一起梳理出来。
1. 先分清 Photon 托管到底解决什么问题
1.1 自建服务器与托管服务器的差别
很多人在浏览器里打开 Gorebox 的多人房间时,以为客户端之间是直接通信的。实际项目中很少这么做。更常见的做法是有一个中心服务器负责转发和同步状态,客户端只和这个服务器通信。Gorebox 这类项目需要处理玩家位置、对象状态、消息广播和房间生命周期,如果每次都由某个玩家的客户端承担服务器职责,就会出现掉线后整个房间不可用、延迟不稳定、无法统一控制版本等一连串问题。
Photon 托管的意义在于把“房间管理”和“消息路由”从游戏逻辑中分离出来。部署 Photon 之后,客户端不再需要知道自己要和哪个玩家建立点对点连接,只需要连接到一个稳定的服务器地址,然后加入指定房间即可。服务器端可以自定义验证逻辑,也可以把玩家事件转发给其他客户端。
自建服务器的典型路径是自己买云主机、装运行时、配置端口、处理安全组、申请域名、维护证书。托管方式的典型路径是把服务端插件部署到 Photon 的管理体系里,由 Photon 处理连接、断线、负载和基础监控。两种方式都能跑通 Gorebox,区别在于你要不要自己处理底层连接。
推荐从 Photon Cloud 或 Photon Server 的本地模式开始。不要一上来就追求最强负载,托管的第一步应该是打通最小联机链路,之后再考虑扩展。
1.2 Photon Cloud 与 Photon Server 的选型差异
Photon 通常有两种使用形态:一种是使用 Photon Cloud 提供的现成服务,你只需要创建应用并获取 AppId;另一种是使用 Photon Server 构建自己的独立服务,你可以完全控制服务器进程、配置和部署位置。这里不评价哪种绝对更好,只说明它们在 Gorebox 托管上的差异。
| 对比项 | Photon Cloud | Photon Server 本地部署 |
|---|---|---|
| 服务器位置 | 由 Photon 运行环境托管 | 自己准备云主机或内网机器 |
| 配置复杂度 | 低,重点是 AppId 和区域 | 高,重点是配置文件和插件编译 |
| 自定义服务端逻辑 | 使用现有应用类型,自定义空间有限 | 可以编写完整服务端插件 |
| 日志和排错 | 通过控制台和运行日志查看 | 直接查看本地日志、性能计数器和后台 |
| 成本模型 | 按并发和流量估算 | 按服务器资源估算 |
| 适合场景 | 想快速跑通联机、团队没有运维力量 | 需要深度控制游戏逻辑、离线开发、隐私要求高 |
在很多真实项目中,团队会先用本地 Photon Server 调试服务端插件,确认逻辑无误后再迁移到在线托管环境,或者继续使用自己的云主机。这里不把两种方式看作对立面,而是看作同一个配置逻辑的不同落地环境。
Gorebox 服务端的业务逻辑越重,越建议使用本地 Photon Server 开发。它的好处在于可以随时打断点、直接看本地日志、不用受托管平台限制。等逻辑稳定后,再把同一套插件部署到生产环境。
1.3 Gorebox 接入 Photon 时的功能边界
Gorebox 接入 Photon 后,哪些功能由客户端处理,哪些由服务端处理,必须在写代码之前确定。一个常见的错误是把所有逻辑都塞给服务端,结果服务端插件变成巨大的状态机,稍有不慎就会出现房间崩溃。
建议按下面的边界来划分:
- 输入采集和本地表现放在客户端,比如键盘鼠标输入、本地动画播放。
- 同步性强的核心状态放在服务端,比如玩家坐标、房间内对象归属、回合状态。
- 非关键表现消息放在客户端本地预测,比如粒子效果、装饰音效。
- 权限和准入逻辑放在服务端,比如玩家加入房间时的校验、房间最大人数限制。
- 聊天、表情这类低频率事件可以走普通事件广播,不必做成高频状态同步。
这里要理解一个原则:Photon 是状态同步和消息分发的基础设施,不是游戏业务服务器。它不会替你判断玩家能不能移动,也不会替你处理 Gorebox 的玩法规则。你需要通过服务端插件定义事件,再把这些事件转发给房间内其他客户端。Photon 只保证你的事件能到达指定目标,不保证你的业务逻辑一定正确。
对新手而言,最容易踩的坑是“客户端能连上就觉得托管成功”。事实上,连接成功只代表客户端和服务端建立了长连接,并不能说明你的业务事件已经正确同步到其他玩家。后面会逐步展开如何验证这一层。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 托管前的环境准备与项目结构
2.1 开发机环境要求
Photon Server 主要运行在 Windows 和 Linux 环境,编写服务端插件通常需要 .NET 环境。Gorebox 服务端项目本身如果由 C# 编写,和 Photon 的融合会相对直接;如果服务端使用其他语言,就要考虑通过 HTTP、TCP 或消息队列和 Photon 的外部扩展接口交互。这里以常见的 C# 插件方式为例展开。
准备环境时,重点检查以下内容:
- 操作系统:Windows Server 2012 R2 以上,或主流 Linux 发行版,具体以 Photon 发行包支持的平台为准。
- 运行时:保证 .NET Framework 或 .NET Core/.NET 版本和 Photon Server 要求一致,不要直接复用其他项目的运行时。
- 端口:默认情况下 Photon Server 暴露 TCP 和 UDP 端口,部署前要确认防火墙和云安全组没有拦截。
- 版本控制:准备 Git、打包工具和构建脚本,服务端插件不能只留在开发机里。
不要把精力全部放在下载工具上。更重要的检查项是端口是否闲置、运行环境版本是否匹配、日志目录是否有写权限。很多配置不生效的问题,最后都出在操作系统权限上。
2.2 下载并安装 Photon Server
安装 Photon Server 时,建议先以本地模式安装一次,目的是熟悉它的目录结构和配置方式。下载得到的是压缩包,包含 deploy、doc、src-server 等目录。不同版本目录名可能不同,落地前先看自带的 README 或文档。
以典型 Windows 目录为例,安装完成后确认以下目录存在:
text复制PhotonServer/
bin/
deploy/
LoadBalancing/
bin/
PhotonServer.config
Service/
Service.dll
doc/
lib/
src-server/
这里最重要的两个目录分别是 deploy 和 lib。deploy 里放的是可运行的服务实例和配置文件,lib 里是 Photon 提供给插件开发的程序集。如果你发现服务端插件引用不到 Photon.Server 等程序集,通常是因为 lib 路径没有被项目引用。
启动前先看默认 PhotonServer.config,不要直接改生产配置。本地跑通后再把修改后的配置放到正式环境。这样能避免配置错误被带到线上。
2.3 准备 Gorebox 服务端项目目录
建议把 Gorebox 服务端插件从主项目里拆出来,单独成一个解决方案。等到后面需要灰度发布时,你会意识到独立项目比单目录结构更容易维护。
最小项目结构可以是这样:
text复制GoreboxServer/
src/
Gorebox.Server/
Gorebox.Server.csproj
GoreboxApplication.cs
GoreboxPeer.cs
config/
PhotonServer.config
publish/
bin/
GoreboxServer 的源码目录不一定要和 Photon 的安装目录放在一起。开发时可以通过复制 DLL 的方式发布到 deploy,也可以通过脚本自动同步。推荐用简单脚本完成“编译 -> 复制 DLL -> 重启服务”三个动作,这样每次修改逻辑后不用手动拖文件。
这里有一个容易被忽略的地方:服务端插件编译目标框架和 Photon Server 进程本身要兼容,否则启动服务时会报 BadImageFormatException 或类似加载错误。遇到这类报错,先检查项目目标框架,再检查 bin 目录里是否混入了不同版本的依赖。
3. 完成服务器配置和应用接入
3.1 PhotonServer.config 关键配置
Photon 服务端的核心配置文件是 PhotonServer.config。它决定 Photon 监听哪些端口、启用哪些应用、日志输出到什么位置。以常见配置为例,一个最简配置文件需要包含 Instances、Applications 和 LogSettings 三部分。
xml复制<PhotonServerConfig>
<Instance1>
<Photon InstanceName="Gorebox"
Port="10555"
PrimaryPort="5055"
UDPPort="5056"
AllowCors="false"
EnableUDP="true">
<Applications Default="GoreboxApp">
<Application Name="GoreboxApp"
BaseDirectory="deploy/GoreboxApp"
Assembly="Gorebox.Server"
Type="Gorebox.Server.GoreboxApplication"
EnableAutoRestart="true"
WatchFiles="false" />
</Applications>
</Photon>
</Instance1>
<LogSettings Level="Info"
Directory="log"
MaxFileSize="20MB"
MaxFiles="10" />
</PhotonServerConfig>
这里有几个参数需要理解,而不是直接照抄。
Port 是 Photon 管理通信使用的端口,PrimaryPort 是客户端主连接端口,UDPPort 是客户端 UDP 连接的端口。客户端连接时必须指定 PrimaryPort 或和 SDK 匹配的默认端口。若客户端使用默认端口而你手动改了 PrimaryPort,就会造成连接失败。
BaseDirectory 是应用根目录,相对路径基于 deploy 目录。路径写错的常见表现是服务启动成功,但访问应用时出现 Assembly not found 或 Application not found。
Assembly 是插件程序集名,Type 是实现了 Photon.Server.PhotonApplication 的完整类名。两者必须和编译产物一致,大小写也要一致。
EnableAutoRestart="true" 表示程序集被替换后自动重启应用,这在开发时很方便。但是生产环境不建议一直开着,因为你的发布脚本可能只复制了一半文件,自动重启会导致启动失败。
日志设置使用 Level 控制输出粒度,Info 会输出连接和事件信息,Debug 会输出更细的内容。生产环境建议先使用 Info,排查问题时临时切到 Debug。
3.2 编写服务端插件
Photon 服务端插件核心工作是从客户端接收事件,处理后广播给房间里其他客户端。Gorebox 服务端插件需要实现的类一般包括一个继承自 PhotonApplication 的主应用类,以及处理具体客户端连接的 Peer 类。
以一个最简 C# 示例说明结构:
csharp复制using System;
using Photon.Server;
using Photon.Sockets;
namespace Gorebox.Server
{
public class GoreboxApplication : PhotonApplication
{
protected override PeerBase CreatePeer(InitRequest initRequest)
{
return new GoreboxPeer(initRequest);
}
protected override void OnServerInitialize()
{
Log.Info("Gorebox Application Initialized");
}
}
}
GoreboxPeer 的关键职责是处理客户端发来的请求。Photon 客户端和服务器之间通过 OperationRequest 和 OperationResponse 交互。一个简单的移动同步事件可以让客户端把目标坐标发送到服务器,服务器再转发给房间内其他人。
csharp复制using System.Collections.Generic;
using Photon.Server;
using Photon.Sockets;
namespace Gorebox.Server
{
public class GoreboxPeer : Photon.Server.PeerBase
{
public GoreboxPeer(InitRequest initRequest) : base(initRequest)
{
}
protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
switch (operationRequest.OperationCode)
{
case 1: // 玩家移动事件
BroadcastPosition(operationRequest);
break;
default:
base.OnOperationRequest(operationRequest, sendParameters);
break;
}
}
private void BroadcastPosition(OperationRequest request)
{
var position = request.Parameters;
var eventData = new EventData(1, position);
SendEventToAll(eventData, new SendParameters());
}
}
}
这里只演示了最小逻辑,实际项目还要处理玩家加入、离开、房间资产加载和状态快照。不要把这些方法直接抄进项目,重点在于理解几个原则:
- 客户端发来的
OperationRequest需要有一个固定的OperationCode约定。 - 服务器向客户端回执结果使用
OperationResponse。 - 服务器主动通知客户端使用
EventData,事件码也要在客户端和服务端之间保持一致。 - 同一个房间内的事件广播使用
SendEventToAll或按目标列表发送,而不是直接操作底层 socket。
3.3 客户端通过 AppId 或端口接入
在 Photon Cloud 模式下,客户端使用 AppId 和地区选择器连接。你需要在 Photon 管理后台创建应用,得到 AppId,然后把它填进客户端的初始化代码。
在本地独立部署模式下,客户端不再使用 AppId,而是直接指定服务器地址和端口。
csharp复制// Photon Realtime 客户端示例,这里只演示连接参数
var connectionInfo = new AppSettings
{
Server = "127.0.0.1",
Port = 5055,
Protocol = ConnectionProtocol.Udp
};
var client = new LoadBalancingClient(connectionInfo);
client.Region = "localhost";
client.AppId = null; // 本地模式通常不使用 AppId
如果用 Photon Cloud,则需要把 Server 换成区域地址,并保持 AppId 有效。这个差别最容易造成“本地能连、发布到线上连不上”的现象。
AppSettings 中还有几个参数会影响连接结果,包括连接协议、端口和自定义负载。不要为了省事把所有客户端都强制使用 TCP。如果客户端网络环境不稳定,UDP 和 TCP 的切换策略要由游戏逻辑决定,不要直接一刀切。
3.4 配置心跳、超时和日志级别
连接建立之后,服务端需要知道客户端是否还活着。Photon 通过心跳和超时机制完成这一判断。默认设置通常能覆盖普通场景,但在高并发或弱网环境下,盲目调高超时会让无效连接占住资源,调低超时又容易造成玩家频繁掉线。
建议把超时分成两级来看:
| 参数位置 | 影响 | 建议 |
|---|---|---|
| 服务端连接超时 | 长时间无数据时主动断开 | 根据玩法内容调整,普通房间建议 10 到 30 秒 |
| 客户端重连策略 | 断线后自动重连的时间间隔 | 递增重连间隔,避免同时风暴 |
| 应用心跳频率 | 服务端和客户端互相确认状态 | 3 到 5 秒一次即可,过于频繁增加包量 |
日志级别方面,开发时用 Debug 能看到每个 OperationRequest 的详细信息,但这会带来大量文件写入。生产环境可以先用 Info,当出现“客户端掉线但服务端没有记录”的问题时,再临时开启 Debug 抓特征。
在正式接入之前,可以让客户端和服务端约定一组测试事件。比如用一个 Ping 操作码,客户端发送当前时间,服务端回显时间戳。这个最小事件能快速验证连接、序列化和日志链路是否正常。
4. 启动、注册和验证托管状态
4.1 命令行启动
本地安装好 Photon Server 后,可以通过命令行启动。Windows 环境下可以使用 PhotonControl 或者直接运行服务端程序。生产环境建议使用系统服务方式管理,避免关掉终端就把服务器停了。
开发机快速启动方式:
bash复制cd PhotonServer/bin
./PhotonServer.Development.exe
如果已经发布到 deploy,并且希望以独立进程方式运行,可以先检查 PhotonServer.config 指向的有效目录,然后启动。启动完成后不要立刻认为成功,要确认进程存在、端口监听、日志开始写入三条信息。
检查端口是否监听,以 Linux 环境为例:
bash复制ss -lntup | grep 5055
ss -lntup | grep 5056
看到 LISTEN 状态后,说明服务端至少已经打开了端口。但端口监听不等于应用加载成功,还需要参考日志文件里的启动信息。
4.2 验证管理后台和日志
Photon 启动后会输出日志文件,路径由 LogSettings 中的 Directory 决定。日志里出现 Started、Application Started 之类内容,只代表应用装载完成。真正有价值的验证是客户端连接时产生的连接事件。
一种验证方式是直接查看控制台输出或日志文件:
text复制2025-01-01 12:00:01 [Info] PhotonServer started
2025-01-01 12:00:05 [Info] Application GoreboxApp started
2025-01-01 12:00:10 [Info] New connection from 127.0.0.1
如果只看到前两行,没有连接事件,说明客户端没有到达服务端,需要继续检查端口和客户端配置。
另一种验证方式是使用管理后台,查看在线人数、房间数量和应用状态。如果管理后台显示应用已注册,但房间数一直是零,问题通常出在客户端还没有成功调用 JoinOrCreateRoom 之类的接口。
4.3 从客户端验证联机状态
客户端验证不能只看“是否连接成功”,还要看是否可以创建房间、加入房间、收到其他玩家的同步事件。建议准备两个客户端实例,用一个账号创建房间,另一个账号加入同一个房间。
验证步骤可以这样组织:
- 客户端 A 调用连接接口,确认连接状态。
- 客户端 A 创建房间,确认在服务端日志看到房间创建记录。
- 客户端 B 使用相同区域和 AppId 加入房间。
- 客户端 A 发送一个移动事件。
- 客户端 B 检查是否收到同一事件。
如果前面几步都成功,客户端 B 却能加入房间但收不到事件,说明问题不在连接层,而在事件广播的OperationCode 或 EventCode 约定不一致。这时候应该同时抓两边的日志,比较玩家发送的事件目标和服务器广播的事件目标。
4.4 学习环境与生产环境的差异
学习环境的重点是快速验证功能,端口、地址和账号都可以很随意。生产环境则必须把以下问题提前想清楚:
- 服务器地址不再使用
127.0.0.1,要替换成客户端可达的公网地址或内网域名。 - 端口要经过防火墙和安全组放行,不能只改配置不开放端口。
- AppId 或服务端证书要按环境隔离,不要把开发环境的密钥用在生产环境。
- 日志保留周期要确定,避免日志文件无限增长。
- 服务端插件要打包成可重复发布的版本,不能每次从开发机复制临时文件。
- 需要准备回滚方案,一旦新版本出现问题,能快速切回上一个稳定版本。
生产环境还要额外考虑监控。最简单的手段是定时检查进程、端口和最近日志时间戳,再高级一点的做法是把 Photon 日志接入集中日志平台。不管使用哪种方式,都要有一个“明显异常时能通知到人”的机制,而不是只靠人工查看。
5. 常见问题排查
5.1 客户端连不上服务器
现象是客户端连接状态一直是 Connecting,超时后直接变为 Disconnected。
排查顺序从客户端配置开始:
- 确认客户端使用的服务器地址不是
127.0.0.1。移动端真机无法直接访问电脑上的回环地址,需要填写电脑的局域网 IP。 - 确认端口和协议一致。客户端使用 UDP,服务端却只开启了 TCP,连接必然失败。
- 确认防火墙没有拦截端口。可以先在服务器本机用客户端连接测试,如果能连上,说明问题在防火墙或云安全组。
- 确认
PhotonServer.config中的应用名和客户端请求的应用名一致。
一个典型的错误是客户端把 localhost 当作生产地址,或者使用了错误的协议类型。推荐先把服务端地址和端口打印在客户端日志里,方便直接对照。
5.2 启动报错 Configuration Error
现象是执行启动命令后立刻退出,日志中出现 Configuration Error 或 Application not found。
这种问题通常有三个原因。
第一个原因是 XML 配置格式错误,比如标签没闭合、属性名写错。检查这类问题可以直接用文本编辑器解析 XML,不要只靠眼睛看。
第二个原因是 Application 的 BaseDirectory 写错。配置文件中的相对路径基于 Photon 主目录,不是当前工作目录。如果应用目录实际位于 deploy/GoreboxApp,就写相对路径 deploy/GoreboxApp,不要写成绝对路径。
第三个原因是 Assembly 或 Type 写错。编译后的 DLL 文件名要和 Assembly 一致,Type 要包括完整命名空间和类名。如果程序集不匹配,日志里会出现加载异常。
解决这类问题时,先切到 Debug 日志,再重新启动服务。大多数加载错误会在日志里打印出具体程序集名,这样可以快速定位。
5.3 连接成功后反复掉线
现象是客户端能连接,但几秒后掉线,重连后还是一样。
可能原因有三个:
- 服务端启用了心跳检测,但客户端心跳没有按要求发送。需要检查客户端是否开启了自动心跳。
- 客户端发送的数据包格式不符合服务端解析逻辑,导致服务端认为客户端异常。该类问题通常伴随绑定或反序列化异常。
- 网络环境本身不稳定,UDP 丢包严重。此时可以暂时切换 TCP 测试,排除网络因素。
排查时先在服务器端查看连接断开前的最后一条日志,确认是服务端主动断开还是客户端断开。如果服务端主动断开,日志里会有超时或错误提示;如果客户端断开,则重点检查客户端异常回调。
实际项目中,反复掉线最常见的原因是客户端探活和服务端超时阈值不匹配。比如服务端 10 秒收不到数据就断开,客户端却只在 30 秒后发一次心跳。解决办法是把服务端超时时间放宽,或把客户端心跳频率提高到服务端阈值的一半以内。
5.4 日志里看不到自定义消息
现象是客户端调用了服务端接口,业务没有生效,但服务端没有打印任何相关日志。
原因多半是事件没有走到你写的 OnOperationRequest 方法。请按这个顺序排查:
- 客户端是否真正调用了
OpCustom或对应 SDK 的请求方法。 OperationCode是否一致,客户端和服务端常量必须完全相同。- 请求是否到达了正确的应用实例。如果部署了多个应用,客户端可能连到了别的应用。
- 服务端日志级别是否过低,导致
Info级别日志被过滤。 - 服务端插件 DLL 是否最新,发布时可能复制到了错误目录。
推荐在服务端 OnOperationRequest 入口先无条件打印一条日志,确认事件能到达。如果入口日志都没有,就要回到连接层排查,不要继续往下查看业务逻辑。
5.5 错误排查清单
| 现象 | 检查点 | 处理方式 |
|---|---|---|
| 客户端连不上 | 地址、端口、协议、防火墙 | 本机测试、查看端口监听、查看日志 |
| 配置错误启动失败 | XML 格式、BaseDirectory、Assembly | 校验 XML、确认路径、开启 Debug 日志 |
| 连接后掉线 | 心跳、超时、数据格式 | 对齐心跳间隔、比较服务端和客户端阈值 |
| 自定义事件不生效 | OperationCode、应用实例、日志级别 | 在入口打印日志、核对常量、确认 DLL 目录 |
| 房间能创建但不同步 | 广播目标、EventCode 约定 | 用两个客户端抓包或打日志对比事件码 |
6. 最佳实践
6.1 发布前检查
发布 Gorebox 服务端之前,建议按一份固定清单检查,避免每次遗漏不同项目。
- 客户端和服务端的事件码、操作码是否记录在同一个文档里。
- 服务端插件是否由构建服务器生成,发布包是否附带版本号。
PhotonServer.config中的端口、应用名、日志目录是否和环境匹配。- 服务器地址是否已经替换成对外地址,而不是开发机地址。
- 安全组和防火墙是否放行客户端端口。
- 日志采集是否就绪,至少保证启动日志能被记录。
- 是否准备了回滚包,回滚后配置和 DLL 能快速恢复。
- 是否确认客户端可以退出房间并重新加入,不残留脏状态。
这些检查项不是一次性的,每次发布都要执行。很多线上事故发生在首次跑通之后的第二次发布,因为团队觉得第一次没问题就跳过了检查。
6.2 日志、监控和回滚策略
服务端托管不是写完代码就结束。进入生产环境后,最需要关注的是日志、监控和回滚能力。
日志方面,不要只在异常时打印日志。可以在关键节点打印玩家进入、玩家退出、房间创建、房间销毁、自定义事件到达等信息。这些日志会成为排错的第一手信息。
监控方面,至少监控四个指标:进程是否存在、端口是否监听、日志文件是否持续更新、房间数量是否在预期范围内。可以写一个简单的定时任务检查进程和端口,比如每 30 秒执行一次检查脚本。
回滚方面,推荐保留上一个正常版本的完整目录。发布新版本时,先把旧版本目录改名或拷贝备份,再把新版本部署上去。如果新版本出现严重问题,直接恢复旧目录并重启服务,这是一种简单但有效的回滚方式。
不要在服务器上手动修改正在运行的 DLL。正确做法是准备一个发布目录,通过脚本完成“停止进程 -> 替换文件 -> 启动进程”三个步骤。这样可以减少“文件被占用”和“一半文件新一半文件旧”的问题。
6.3 可复用的托管清单
这里给出一份可复用的托管清单,适合每次部署前逐项检查。
环境类
- 本机运行环境和服务器运行环境是否一致。
- 端口是否被其他进程占用。
- 防火墙和安全组是否放行 TCP/UDP 端口。
- 日志目录是否有剩余磁盘空间。
配置类
- 主配置使用相对路径还是绝对路径,是否会被环境差异影响。
EnableAutoRestart是否只保留在开发环境。- 日志级别是否设置为合适级别。
- 应用名和客户端配置是否一致。
代码类
- 服务端和客户端事件码、操作码保持一致。
- 玩家进入、离开房间时是否处理了状态清理。
- 服务端是否存在无限制的广播或循环。
- 服务端对非法请求是否有拒绝逻辑。
发布类
- 发布包是否包含完整依赖。
- 是否执行过至少一次从空目录到启动成功的完整发布。
- 是否验证过从旧版本回滚到新版本再回滚旧版本的流程。
- 是否用两个客户端完成过联机验证。
运行类
- 服务器启动后是否能用命令行确认端口监听。
- 日志是否持续写入。
- 客户端连接后,服务端是否有对应连接日志。
- 房间创建和加入是否正常。
- 长时间运行后内存和 CPU 是否有异常增长。
这份清单建议放在项目目录里,和发布脚本放在一起。每次执行发布时按顺序打勾,能明显减少低级错误。
6.4 后续扩展方向
Gorebox 服务端接入 Photon 只是托管的第一步。后续可以从几个方向继续深入:
- 把玩家数据持久化到数据库,避免重启服务器后玩家状态丢失。
- 引入服务端权威校验,防止客户端伪造移动或攻击数据。
- 使用多应用实例部署,根据在线人数动态扩容。
- 把日志接入集中日志平台,用关键词检索代替人工翻文件。
- 建立自动化测试,模拟一批客户端同时加入和退出房间,检查资源释放是否正常。
如果只是想完成任务,跑通最小链路就够了。如果目标是长期维护,一定要在托管第一天就建立发布、回滚和监控的规范。否则项目越来越大之后,每一次配置修改都会变成一次赌博。
Photon 托管最核心的判断是:连接层只是起点,业务层的稳定才决定玩家体验。把事件约定、配置管理和发布流程固化下来,Gorebox 服务端才能真正脱离“开发机能跑”的阶段,进入可维护的生产状态。
