扩展 SDK 组件
最后更新:2026 年 7 月 16 日
这套机制让开发者可以在不改动组件本身的前提下,扩展组件的行为。
需要扩展某个组件的功能时,PlayServ 用的是 Handler。Handler 让你把自己的逻辑挂到组件的某个方法上,而不必重写这个组件。
何时扩展 SDK 组件
以下情况使用组件扩展:
- 给组件已有的某个方法加上自定义规则 —— 比如放行或拒绝一次 join
- 把游戏特有的行为塞进组件的标准流程里
- 给同一个扩展点挂上多个彼此独立的 Handler
扩展组件的方法
例子:扩展 Group 组件的 Join 方法。
// Extend the Join method
PlayServ.Server.Group("Game")
.ExtendMethod(PlayServ.Server.Group.Join, user => {
return false; // abort pipeline
})
// sugar
.DoJoin(user => { ... });
组件执行 Join 操作时,Pipeline 是这样跑的:
组件开始处理
组件为 Join 操作启动它的处理流程。
执行各个 Handler
已注册的 Handler 按顺序执行,形成一条中间件链。
某个 Handler 返回 false
只要有任何一个 Handler 返回 false,Pipeline 立即停止。
操作被取消
Join 操作被取消,后续的 Handler 不再执行。
Handler 可以 中止中间件 Pipeline。返回 false 会终止后续处理并取消这次操作。
Handler 是怎么执行的
Handler 作为中间件 Pipeline 的一环执行。正因如此,同一个扩展点才能注册多个 Handler,同时每个 Handler 的实现又都能保持很小。
对所有组件都适用
这套做法适用于任何组件。有些组件会在自己的 API 中保留特定的 RPC 方法,并明确标记为可扩展。这些方法参与组件的生命周期,在特定条件下由组件自己调用。
有些组件以保留 RPC 方法的形式,对外提供明确的扩展点。这些方法属于组件生命周期的一部分,在特定条件下由组件自身调用。
例子:为对战 Room 做受控的 Join
场景: 你有一个对战 Room,Player 可以进入。客户端用的是标准的 Join() 调用,但要不要放人进来得由服务端决定。典型的 gameplay 规则包括:
- 对战已经开始
- Room 已满
- 该用户在此模式下被封禁
- 该用户不满足段位或等级要求
你不需要替换 Groups 组件,也不需要另起一个自定义 RPC 方法。做法是扩展标准的 Join 方法,在服务端施加规则,而客户端的调用保持原样。
流程:
客户端调用 Join()
客户端在目标 Group 上调用 Join()。
服务端运行 Join 的 Pipeline
服务端执行 Join 的中间件 Pipeline,逐个跑过已注册的规则 Handler。
某条规则没通过
只要有规则不通过,对应的 Handler 就返回 false,Pipeline 随之中止 —— 这次 join 被拒绝。
所有规则都通过
全部规则通过后,join 获准,Handler 正常结束。
客户端:
await PlayServ.Group("Game").Join();
服务端:
PlayServ.Server.Group("Game")
.ExtendMethod(PlayServ.Server.Group.Join, user => {
// Gameplay checks
bool roomIsFull = false;
bool matchAlreadyStarted = false;
bool userIsBanned = false;
bool requirementsNotMet = false;
if (roomIsFull || matchAlreadyStarted || userIsBanned || requirementsNotMet)
return false; // abort pipeline -> Join is rejected
return true; // allow Join to proceed
})
// sugar: the Join handler itself
.DoJoin(user => {
// Optional: actions on successful join
// e.g. attach user to match context
return true; // accept user into the group
// return false; // reject
});