多人游戏会话目录概述

本主题介绍多人游戏会话目录 (MPSD) 服务如何使游戏共享连接一组用户所需的基本信息。

当发送和接受邀请以及用户通过游戏卡加入时,MPSD 与 shell 和控制台操作系统进行协调。

MPSD 集中存储多个客户端系统的多个游戏系统元数据。 MPSD 确保会话功能已同步并保持一致。

MPSD 是在 Xbox 服务云中运行的服务。 它由 XblMultiplayer 函数包装。

本主题涵盖以下内容:

MPSD 会话

MPSD 会话由其 XblMultiplayerSessionHandle 标识,表示一个或多个用户玩游戏的方案。 会话由 MPSD 作为安全 JSON 文档存储在 Xbox 服务云中。

具体来说,MPSD 会话具有以下特点。

  • 由游戏创建和管理。
  • 其具有唯一的 URI。 有关详细信息,请参阅会话目录 URI
  • 支持用户 (称为会话成员) 之间的连接。
  • 它存储启用游戏的数据,如按成员属性、游戏设置、启动信息和游戏服务器信息。

每个会话包含玩家的 Xbox 用户标识符 (XUID) 和安全设备关联地址数据。

MPSD 支持多种类型的会话来设置各种类型的多人游戏,包括以下变体。

会话变体 说明
游戏会话 游戏的模式。 游戏会话可以是点对点、点对主机、点对服务器或这些类型的混合。
票证会话 用于在匹配期间跟踪匹配状态的辅助程序会话。 它经常还是大厅会话,有时可能是游戏会话。 有关详细信息,请参阅匹配概述
目标会话 在匹配期间创建的用于表示匹配游戏的辅助程序会话。 它几乎始终还是一个游戏会话。 有关详细信息,请参阅匹配概述
大厅会话 用来容纳等待加入游戏会话的受邀请玩家的帮助程序会话。 许多游戏既创建大厅会话也创建游戏会话。

返回到本主题顶部。

MPSD 更改通知处理和断开连接检测

客户端通过使用实时活动 (RTA) 服务 Web 套接字连接到 MPSD。

连接用于执行以下操作:

  • 当会话更改发生时,根据作品启动的事件订阅向下发送简要通知(即时点击)。
  • 检测用户断开连接的情况。
  • 根据断开连接检测将用户设置为非活动,然后将其从会话中删除。

建立用户连接

Xbox 服务 API (XSAPI) 库管理客户端与 MPSD 之间的连接。

  1. 游戏会调用 XblMultiplayerSetSubscriptionsEnabled。 此方法告诉 XSAPI,客户端打算使用 RTA 连接来支持多人游戏。

  2. 当游戏首次调用 XblMultiplayerWriteSessionAsyncXblMultiplayerWriteSessionByHandleAsync,且当前用户设置为“活动”状态时,将创建连接并关联到 MPSD。

注意

若要启用会话通知并检测断开连接,会话模板必须将 connectionRequiredForActiveMembers 设置为 true

订阅会话更改

MPSD 使用即时点击作为感兴趣事物发生更改时发出的轻型通知。 启用订阅后,游戏可通过调用 XblMultiplayerSessionSetSessionChangeSubscription 来订阅有关会话更改的即时点击。

有关详细信息,请参阅在多人游戏任务主题中的 订阅 MPSD 会话更改通知 部分。

手柄肩部点击

当对某个会话所做的更改与游戏针对该会话的订阅匹配时,MPSD 通过使用 XblMultiplayerSessionChangedHandler 处理程序来向游戏发送有关所做更改的通知。 作品随后应该检索会话,并将检索到的会话版本与之前缓存的视图进行比较,并执行相应的操作。

处理连接状态更改通知

作品可以接收与 MPSD 的连接的运行状况变化相关的通知。

两个事件可表明这些更改。

断开客户端连接

当游戏通过调用 XblMultiplayerSetSubscriptionsEnabled 禁用通知时,游戏的客户端将断开与 MPSD 的连接。 在该调用之后不久,XblMultiplayerSessionSubscriptionLostHandler 处理程序将触发,表明客户端已断开与 MPSD 的连接。

注意

在早期的多人游戏版本中,游戏调用 XblRealTimeActivityDeactivate 以与 RTA 服务断开连接。 对于 2015 多人游戏服务,此方法不起作用。 使用 false 值调用 XblMultiplayerSetSubscriptionsEnabled 后,如果没有 Web 套接字连接的用户 (如 RTA 服务订阅到状态服务),则会自动断开连接。

断开连接检测

MPSD 使用断开连接检测功能快速发现用户的非正常断开。 不正常断开连接的原因包括当玩家的网络故障或游戏崩溃时。

MPSD 将断开连接的玩家的状态从“活动”更改为“非活动”,并根据情况、基于成员的会话订阅,通知其他会话成员这一更改。

处理 RTA 重新连接

XSAPI 尝试在断开连接时重新连接到 RTA,并重新提交 RTA 订阅。 (有关更多信息,请参阅 RTA 服务的最佳做法。) 重新提交多人游戏 RTA 订阅会更新用于将 MPSD 会话中的用户与客户端 RTA 连接相关联的连接 ID。

XSAPI 通过 XblMultiplayerAddConnectionIdChangedHandler 通知游戏 MPSD 连接 ID 已更改。 在回调内部,游戏必须将新的连接 ID 写入 MPSD 会话。 可以通过调用 XblMultiplayerSessionCurrentUserSetStatus 将新的连接 ID 写入会话,然后通过调用 XblMultiplayerWriteSessionAsync 向会话写入内容。

void* context{ nullptr };
XblFunctionContext connectionIdChangedFunctionContext = XblMultiplayerAddConnectionIdChangedHandler(
    xblContextHandle,
    [](void* context) {
        XblMultiplayerSessionHandle sessionHandle; // Retrieve the MPSD session to update
        XblMultiplayerSessionCurrentUserSetStatus(sessionHandle, XblMultiplayerSessionMemberStatus::Active);

        auto asyncBlock = std::make_unique<XAsyncBlock>();
        asyncBlock->queue = queue;
        asyncBlock->context = nullptr;
        asyncBlock->callback = [](XAsyncBlock* asyncBlock)
        {
            std::unique_ptr<XAsyncBlock> asyncBlockPtr{ asyncBlock };

            XblMultiplayerSessionHandle sessionHandle;
            HRESULT hr = XblMultiplayerWriteSessionResult(asyncBlock, &sessionHandle);
            if (SUCCEEDED(hr))
            {
                // If the write call succeeds, the connection ID has been updated and no further action is needed.
            }
            else
            {
                // If the write call fails, it's likely that the user has been removed from the session.
            }
        };

        auto hr = XblMultiplayerWriteSessionAsync(xblContextHandle, sessionHandle, XblMultiplayerSessionWriteMode::UpdateExisting, asyncBlock.get());
        if (SUCCEEDED(hr))
        {
            asyncBlock.release();
        }
    }, 
    context);

返回到本主题顶部。

MPSD 会话句柄

MPSD 会话句柄是对还可以包含其他类型数据的会话的抽象且不可变的引用。 它类似于文件句柄。 所有句柄都具有句柄 ID (GUID) 和完整的会话引用,其中包括服务配置 ID (SCID)、会话模板和会话名称。 句柄无法更新,但可以创建、读取和删除。

注意

警报注意: 句柄可以指向不存在的会话。 通过使用不存在的会话名称创建句柄不会导致创建新会话。

句柄类型

2015 多人游戏支持邀请句柄和活动句柄。

邀请句柄

邀请句柄表示对某用户的邀请。 类型特定数据包括源用户、目标用户和描述邀请的上下文字符串,例如,特定游戏模式。

邀请句柄授予对开放会话的读写访问权限。 如果会话已关闭,句柄则授予会话的只读访问权限。

注意

即使会话已满或已关闭,MPSD 也可以创建邀请。

创建邀请句柄

为了创建邀请句柄,游戏将调用 XblMultiplayerSendInvitesAsync。 此方法在通知中向指定用户发送一个邀请,收件人可以对其执行操作以接受邀请。

创建活动句柄

为了创建活动句柄,游戏将调用 XblMultiplayerSetActivityAsync。 MPSD 会将新的句柄 ID 设置为会话成员的绑定活动。

如果存在之前的绑定活动,MPSD 将删除对应的句柄。 当活动成员进入非活动状态或离开会话时,MPSD 将删除绑定活动句柄。

使用句柄

当用户接受邀请(邀请句柄)以及用户加入好友的当前活动(活动句柄)时,作品使用句柄。

在这两种情况下,游戏必须执行以下操作。

  1. 从作品激活参数获取句柄 ID。
  2. 创建本地 MPSD 会话对象,然后将其作为活动对象加入。
  3. 写入会话,传入相应句柄。

返回到本主题顶部。

会话更新的同步

会话是可由其任何成员创建或更新的共享资源。 因此,可能会发生冲突的写入。 如果例如一个游戏覆盖了另一个游戏所做的更改,则可能导致意想不到的结果。 MPSD 解决这些冲突的方法是支持开放式并发和读取-修改-写入模式。

MPSD 执行的会话更新同步使用两个相关的高级实现模式。

  • 仲裁程序更新共享的会话部分。 如果您的实现涉及单个仲裁程序,您可以避免为大多数写入操作使用同步更新。 对于以下情况,游戏可以避免同步。

    • 仲裁程序对会话的共享部分进行的任何更新,除非它们与传达仲裁程序的标识相关
    • 游戏对会话中的成员区域进行的任何更新

    注意

    尽管前面提到的更新类型不需要同步,但同步对 XblMultiplayerSessionProperties::HostDeviceToken 属性的任何更新仍然很重要。 该属性用于传达仲裁程序的身份,例如,作为仲裁迁移的一部分。

  • 所有客户端更新共享的会话部分。 在此情况下,必须同步共享的会话部分的所有更新。 但是,游戏仍可在不同步的情况下在自己的成员区域写入。

使用多人游戏 API 更新会话同步

以下多人游戏 API 方法实现了开放式并发。

每个写入方法都接受 XblMultiplayerSessionWriteMode 值。 传递值 SynchronizedUpdate 对更新使用乐观的并发方式。

枚举中的其他值帮助解决初始创建会话后可能出现的冲突。 对 MPSD 会话的某部分(该会话有可能被另一个作品写入)的任何写入均必须使用同步更新。 但是,并非所有的写入都必须受到保护。

如果游戏尝试使用写入会话方法之一将本地会话对象写入 MPSD,则可能会收到 HTTP/412 状态代码。 在这种情况下,它应通过发出 XblMultiplayerGetSessionAsync 调用来刷新本地副本,以便在再次尝试写入之前获得最新的服务器版本会话。 否则,本地会话文档将仍包含错误的数据,并且用于写入会话的调用将继续失败。

注意

当游戏调用其中一个写入会话方法时,可能会返回该会话的更新版本。 如果返回会话的更新版本,游戏应以线程安全的方式将其本地缓存的副本切换到此新版本。

使用多人游戏 REST API 更新会话同步

MPSD 通过 REST 功能在会话更新中支持开放式并发,方法是使用具有 ETag 设置和读取-修改-写入模式的 HTTP "if-match" 标头。 传入写入请求的 ETag 应该是 MPSD 通过之前的读取请求返回的那一个。

返回到本主题顶部。

调用 MPSD

游戏可以通过以下方式访问 MPSD,以使用多人游戏系统和匹配。

  • 建议使用多人游戏 API,其中包含充当 RESTful 功能包装器的类。 有关更多信息,请参阅 XblMultiplayer 前缀函数。 对于 SmartMatch 匹配,请使用由 XblMatchmaking 前缀函数代表的匹配 API。
  • 使用对多人游戏和匹配 REST API 的直接标准 HTTP 调用,这些 API 包含在 Xbox 服务 RESTful 引用中。 在会话目录 URI (适用于多人游戏) 和匹配 URI (适用于匹配) 部分介绍了适用的 URI。 关于 JSON 对象的介绍,详见 JavaScript 对象表示法 (JSON) 对象参考部分。

使用多人游戏 API 调用 MPSD

建议使用 XSAPI 中的多人游戏和匹配 API 调用 MPSD。

注意

这些示例是通过使用 XSAPI 的多人游戏和匹配 API 以及其他元素编写的。

使用包装代码实现基础 REST 功能,以更传统的方式使用客户端 API 方法,而无需处理每个调用的 HTTP 流量。

使用多人游戏 REST API 与 MPSD 交互

游戏或其服务可以使用对多人游戏 REST API 和匹配 REST API 的标准 HTTP 调用。 直接使用 REST 功能时,调用方会针对大多数操作对会话目录 URI 发出 DELETEPUTPOSTGET 调用。 在 PUT 请求中,请求正文合并到现有会话中。

如果没有现有会话,则使用请求主体以及存储在 合作伙伴中心 的会话模板创建新会话。

所有字段都是可选的,只有增量必须指定。 因此,{} 是增量为零的有效 PUT 请求。

若要执行返回合并结果的假设 PUT 请求而不影响服务器的官方会话副本,可以将查询字符串 ?nocommit=true 附加到 PUT 请求中。

多人游戏和匹配 REST API 方法的请求和响应是 JSON 文档。 有关多人游戏会话请求的结构,请参见 MultiplayerSessionRequest (JSON)

关联的响应结构显示在 MultiplayerSession (JSON) 中。 响应结构将会话成员构建为链接的列表,并填充会话及其成员的其他只读属性。

查询会话和会话模板 (REST)

您的作品可以在服务配置和会话模板级别查询会话信息。 本部分介绍使用多人游戏 REST API 的查询。

查询基本会话信息

可以通过使用会话目录和匹配 URI 来设置基本会话信息的查询。 查询结果是一个会话引用的 JSON 阵列,其中内联包含了一些会话数据。 默认情况下,一个查询最多可检索 100 个非专用会话。

注意

每个查询必须包括关键字筛选器、XUID 筛选器或两者都有。

查询会话模板

要检索 SCID 的会话模板列表,以及特定会话模板的详细信息,请为以下 URI 之一使用 GET 方法。

  • /serviceconfigs/{scid}/sessiontemplates
  • /serviceconfigs/{scid}/sessiontemplates/{sessionTemplateName}

查询会话状态

若要查询会话状态,请使用以下 URI 之一的 GET 方法。

  • /serviceconfigs/{scid}/sessions
  • /serviceconfigs/{scid}/sessiontemplates/{sessionTemplateName}/sessions

返回到本主题顶部。

多人游戏会话资源管理器

多人游戏会话资源管理器是一个内置于 MPSD 的工具,用于浏览会话、会话模板和本地化字符串。 该工具仅用于开发沙盒。

访问多人游戏会话资源管理器

注意

要使用该工具,您必须登录。 浏览仅限于以登录用户作为成员的会话。

若要访问多人游戏会话资源管理器,请在 Xbox One (或更高版本) 控制台上打开浏览器,按 查看 按钮,然后在 地址 框中输入 https://sessiondirectory.xboxlive.com/debug

注意

如果您尝试在零售沙盒中访问该工具,您将收到 HTTP/404 状态代码。 有关此状态代码的更多信息,请参阅 多人游戏会话状态代码

打开主页面

  1. 打开工具的主页。 它显示安全环境 (登录用户和沙盒) 和沙盒中的 SCID 列表。

  2. 菜单 按钮将此页面固定到“主页”,这样就无需重新输入 URI。

显示可用会话和模板

  1. 在工具中选择一个 SCID,以显示该 SCID 中包括登录用户的会话列表。

  2. 在同一页面上可以选择 SCID 并显示 SCID 的服务配置中的会话模板和本地化字符串。 这些项目通过合作伙伴中心引入。

显示会话的完整内容

在多人游戏会话资源管理器中,选择会话名称可以显示相应会话的完整内容。

MPSD 显示的会话可能由于以下原因与会话 URI 的标准 GET 方法的响应不同。

  • GET 调用可能在 X-Xbl-Contract-Version 标头中使用较旧的协定版本。 多人游戏会话资源管理器始终使用最新的协定版本来显示会话。

  • 当通过 GET 正常请求会话时,可能触发转换和负面影响,例如,到期超时。 多人游戏会话资源管理器在存储会话时显示会话的快照,而不执行任何逻辑、转换或副作用。

  • MPSD 会话中不存在 nextTimer JSON 对象字段,因为它是与副作用同时计算的。

返回到本主题顶部。

另请参阅

返回到本主题顶部。