调用 Xbox 服务的最佳做法

可以通过两种主要方式调用 Xbox 服务:使用 Xbox 服务 API (XSAPI),或者直接调用 REST 终结点。 无论代码如何调用 Xbox 服务,都必须具有正确的调用模式和重试逻辑。

要了解如何编写正确的重试逻辑,必须了解两类 REST 终结点 - 幂等非幂等。 下面介绍了这些终结点。

非幂等终结点

在重复调用时会产生副作用的 HTTP 方法被视为是非幂等。 这意味着,如果客户端将调用此终结点且发生网络超时,则重试此方法不安全,因为资源可能已更新,但网络无法通知已成功的调用方。

发生错误时,客户端必须先查询以确定调用是否成功,而不是重试。 仅当调用不成功时才应重试。

在 Xbox 服务 API 中,某些 API 已在内部标记为调用非幂等终结点。 这意味着,如果在调用这些终结点时发生故障,则 API 不会自动重试终结点。

完整的非幂等 API 列表如下:

幂等方法

从另一方面来说,幂等 HTTP 方法没有副作用。 这反过来意味着可以安全地重试。 在 Xbox 服务 API 中,在特定条件下,将会自动重试所有幂等方法。

完整的幂等 API 列表为上面未列为非幂等 API 的所有 API。

重新逻辑最佳做法

对于幂等调用,应该会自动重试这些条件:

  • 所有网络错误
  • 401:未授权
  • 408:请求超时
  • 429:请求过多
  • 500:内部错误
  • 502:网关错误
  • 503:服务不可用
  • 504:网关超时

在 UWP 上,将对“401:未授权”进行特殊处理。 此值表示 Xbox 服务身份验证令牌已过期,因此 Xbox 服务 API 将调用操作系统以刷新令牌并作为单次重试执行。

执行重试时,在达到“重试后”标头时间之前,最好不好调用此服务。 XSAPI 现在实施此最佳做法。 如果 HTTP 状态代码发生故障且任何 API 返回“重试后”标头,则在重试后时间之前对此相同 API 的其他调用将会立即返回原始错误,且不会使用此服务。

重试调用时,最佳做法是通过随机抖动执行指数后退,以便将负载扩展到该服务。 XSAPI 将从默认延迟 2 秒开始,该延迟是使用 XblContextSettingsSetHttpRetryDelay 控制的。 这意味着,默认情况下,每次重试以 2、4、8 秒(以此类推)的指数后退。 它将根据响应时间抖动当前与下一次后退值之间的延迟,以便将负载进一步扩展到尝试重试的设备集中。

游戏应控制重试调用所花的时间。 使用 XSAPI,开发人员可以使用函数 XblContextSettingsSetHttpTimeoutWindow 直接控制它。 默认情况下,此值设为 20 秒。 将此值设置为 0 秒将有效关闭重试逻辑。

内部 HTTP 超时的动态调整

XSAPI 会根据 XblContextSettingsGetHttpTimeoutWindow 中剩余的时间量来动态调整内部 HTTP 超时。

内部 HTTP 超时控制操作系统在中止之前进行 HTTP 网络操作所花的时间。

除非 XblContextSettingsGetHttpTimeoutWindow 中还剩下至少 5 秒钟,以便有足够的合理时间完成调用,否则不会重试该调用。 此规则不适用于第一个调用,因此将 XblContextSettingsSetHttpTimeoutWindow 设置为 0 是可以接受的,并且将产生单个调用。

此逻辑的作用是,XblContextSettingsGetHttpTimeoutWindow 对于 API 调用将返回的时间更具有确定性。

如果返回“重试后”标头,则在达到“重试后”时间之前不会进行任何重试。 如果“重试后”时间在 XblContextSettingsGetHttpTimeoutWindow 之后,则调用将在 XblContextSettingsGetHttpTimeoutWindow 结束时返回。

错误处理

游戏开发者在每次服务调用时应始终使用正确的错误处理,并且需要确保正确处理故障响应。

许多的实际情况可能会导致请求 Xbox 服务返回故障代码,如:

  • 网络不可用。 例如,设备丢失 4G、失去 Wi-Fi 连接或网络关闭。
  • 服务上的多个负载过载 (503)。
  • 服务上发生故障 (500)。
  • 发送给服务的请求过多 (429)。
  • 写操作冲突 (412)。 例如,多人游戏会话中的另一个玩家先提交了更改。
  • 用户已被禁止或没有权限。
  • 用户已注销。

正确的错误处理程序对于确保游戏在这些条件下正确运行非常重要。

有关错误处理的最佳做法的详细信息,请参阅错误处理

如需观看介绍此功能的视频,请参阅名为 XSAPI:C++,无异常!Xfest 2015 视频中的访谈

最佳调用模式

使用批处理请求

某些终结点支持将一组请求批处理或聚合为单次调用。 例如,借助 Xbox 服务档案服务,你可以请求单个用户的档案或一组用户的档案。

因此,如果您需要一组用户的档案,那么,一次调用每个用户档案的一个终结点或 API 的效率就非常低。

每次调用都会增加大量身份验证开销。 相反,将您需要其相关信息的所有用户一次传递至 API,使得终结点可以同时处理所有用户档案并返回单个响应。

使用实时活动 (RTA) 服务而不是轮询

一项最佳做法是使用实时活动 (RTA) 服务而不是定期轮询。 实时活动服务会公开一个 Web 套接字,后者会在服务上的目标资源更改时向客户端发送通知。

RTA 服务将提供与状态更改、统计信息更改、多人游戏会话文档更改和社会关系更改相关的通知。

若要了解客户端感兴趣的信息,客户端必须先通过 Web 套接字订阅项目。 这可避免通过轮询服务检测更改,因为系统会告知您项目更改的准确时间。

XSAPI 将 RTA 服务作为客户端可使用的一组订阅 API 公开。 这些 API 每个均具有对应的 *ChangedHandler API,它们使用项目更改时将会调用的回调函数。

  • XblPresenceSubscribeToDevicePresenceChange
  • XblPresenceSubscribeToTitlePresenceChange
  • XblUserStatisticsSubscribeToStatisticChange
  • XblSocialSubscribeToSocialRelationshipChange

使用 XSAPI 客户端侧管理器

XSAPI 包含一组管理器,用作在特定情况下负责繁重工作的缓存和状态机。

社交管理器

社交管理器负责与好友列表和档案相关的所有繁重工作。 社交管理器使用 RTA 服务使您的好友列表、好友档案及其状态数据保持最新。

社交管理器将公开一个对游戏引擎非常友好的同步 API。 游戏可以频繁调用社交管理器 API,因为社交管理器可以通过服务维持内存内缓存的最新信息。

请参阅社交管理器

多人游戏管理器

对于多人游戏会话管理,多人游戏管理器是一个适合于传统多人游戏的普适型解决方案。 多人游戏管理器 API 包括玩家名单和会话管理、处理游戏邀请、加入游戏、匹配和插入现有的网络解决方案。 它负责与实施传统多人游戏流相关的繁重工作。

请参阅多人游戏管理器

节流(细化速率限制)

Xbox 服务具有适当的节流机制,用于防止单个设备对服务施加极端负载。 必须了解游戏被节流的时间。

要确定您的游戏是否被节流,请使用以下方法之一:

  • 监视是否存在 HTTP 状态代码 429
  • 使用调试断言
  • 使用 Xbox 服务跟踪分析器工具

下面介绍了这些方法。

监视是否存在 HTTP 状态代码 429

您可以使用 Fiddler 并监视是否返回 HTTP 状态代码 429。 JSON 响应将包含与终结点如何被节流相关的详细信息。

例如:

{
  "version":1,
  "currentRequests":13,
  "maxRequests":10,
  "periodInSeconds":120,
  "limitType":"Rate"
}

如果你使用的是 XSAPI,则 API 将返回 HTTP_E_STATUS_429_TOO_MANY_REQUESTS 错误,并设置错误消息以显示有关如何限制 API 的详细信息。

使用调试断言

使用 XSAPI 时,如果调用在处于开发者沙盒中时被节流且使用的是调试版本的游戏,则它将断言立即让开发者知悉已发生节流。 这是为了避免因不正确的编写代码而意外丢失 429 节流错误。 如果你想要在不修复问题代码的情况下禁用这些断言以继续工作,则可以使用 XblDisableAssertsForXboxLiveThrottlingInDevSandboxes API:

XblDisableAssertsForXboxLiveThrottlingInDevSandboxes(
    XblConfigSetting::ThisCodeNeedsToBeChanged
);

请注意,此 API 不会阻止游戏被节流。 您的游戏仍将被节流。 这只会在使用调试版本时在开发者沙盒中禁用断言。

使用 Xbox 服务跟踪分析器工具

另一种确定游戏是否被节流的方法是记录 Xbox 服务调用跟踪,然后使用 Xbox 服务跟踪分析器工具分析该跟踪。

要记录轨迹,您可以使用 Fiddler 记录 .SAZ 文件,或使用 XSAPI 内置轨迹日志记录。 有关在 XSAPI 中启用跟踪的详细信息,请参阅 Xbox 文章 Xbox 服务跟踪分析器 (XblTraceAnalyzer.exe)。 获得跟踪之后,Xbox 服务跟踪分析器工具将在检测到节流调用时发出警告。

Xbox 服务是否已启动?

Xbox 服务是一系列微服务集合,用于公开 Xbox 服务功能,如档案、好友和状态、统计信息、排行榜、成就、多人游戏和匹配。 没有单个服务器或终结点定义 Xbox 服务是否已启动。 如果单个服务器关闭,则 Xbox 服务的其余微服务在很大程度上是独立的并且应该可以正常运行。

如果单个服务遇到临时中断,则必须知道此服务调用对你的游戏来说是否是关键任务。 虽然存在间歇性网络或服务问题,但我们仍尝试提供合理体验。 例如,如果状态服务返回故障,则该调用对你的游戏来说可能不是关键任务。 因此,只需向用户报告上次已知状态,无需报告 Xbox 网络(也称为 Xbox Live)已关闭。

Xbox 服务遵循“最终一致性”的一致性模型。 这意味着,如果没有新的更新,则对该资源的所有最终请求将报告最后更新的值。 这意味着数据传播时在一小段时间内信息是过时的。