- 设备 - 在物理设备上执行的游戏的一个独立实例。只要使用 API,就存在一个本地设备。
- 用户 - 单个已登录的玩家,或者更准确地说,是游戏为身份验证和识别目的提供给 PlayFab Party 的 PlayFab
title_player_account实体。一个或多个用户与给定的设备关联。 - 网络 - 游戏为交换聊天或数据通信而创建的一个安全集合,包含一个或多个设备及其授权用户。网络通常与游戏的多人游戏会话或聊天派对概念对齐。
- 端点 - 在网络内发送和接收数据的抽象。端点可以代表一个设备、一个用户或任何所需的游戏特定概念。
- 聊天控件 - 专门用于在一个或多个网络中配置、发起和定向语音与文字聊天的用户表示。
对象关系
作为简化的概念层次结构,网络包含设备,后者又包含用户、可选的端点和可选的聊天控件。例如: 虽然足够简单易懂,但前述关系图实际上是对 PlayFab Party 功能的不完整描绘,单独看可能会产生误导。实际上,Party API 支持设备一次连接到 多个 网络。例如,人们可能希望随着时间的推移与一组朋友保持通信,而同一组人也与陌生人一起加入和离开各种更大的游戏会话。考虑这种更广泛的场景可以让我们更好地理解这些对象之间的关系。 将设备概念化为_属于_网络可能感觉直观,但事实并非如此。更准确的做法是意识到设备_参与_网络。因此,Party 库对于遇到的特定实例,无论其与本地设备共享多少个网络,始终只创建一个设备 API 对象(无论是远程还是本地)。 例如,下图显示了两个网络和三台带用户、聊天控件和端点的设备。 设备 A 及其两个聊天控件(与关联的用户)参与 网络 1,而 设备 B 和 C 各自使用一个聊天控件(与关联的用户)同时连接到 网络 1 和 网络 2。所有设备都在其所连接的每个网络中创建了一或两个端点: 在图中,每台设备都看到所有三台设备及其聊天控件的单个实例,因为它们彼此之间至少共享一个网络。 设备 A 只知道 网络 1 中的 端点 1-4,但 设备 B 和 C 也能看到它们在 网络 2 中创建的 端点 5-7。 如果 设备 C 改为仅参与 网络 2 而不同时参与这两个网络,则:- 设备 C 显然无法在 网络 1 中创建 端点 4,也看不到 端点 1-3。
- 设备 C 不会知道仅存在于 网络 1 中的 设备 A 或其两个聊天控件。
- 设备 A 类似地不会看到仅存在于 网络 2 中的 设备 C 或其聊天控件。
不要求游戏同时连接到多个网络才能成功使用 PlayFab Party。你可以在后续高级主题中了解更多关于是否以及如何使用多个网络的信息。
通用对象属性
所有对象都有明确定义的生命周期。本地游戏实例直接或使用标准化通知机制创建和销毁每个对象,这些通知机制仅在游戏选择的时间窗口期间发出信号。稍后的主题将更详细地描述如何处理通知。 所有 PlayFab Party API 对象也都支持_自定义上下文_的概念,这就是一种在对象上存储可选、仅本地的“快捷方式”指针或值的方法。自定义上下文可以轻松地从 PlayFab Party 对象返回到内存中相应的私有游戏对象(如果有),而无需执行低效的查找。这些值不会远程传输,因为指针值只对本地游戏实例有意义。 最后,除网络以外的上述所有对象都有一个专用的“Local”子对象,其中包含仅对拥有该对象的本地设备可用的方法和属性。 例如,有一个用于表示任何本地或远程端点的基类PartyEndpoint 对象,以及一个更特定的 PartyLocalEndpoint 对象,只有当端点实际由本地设备创建时,才能通过 PartyEndpoint::GetLocal() 检索该对象。这是公开用于传输游戏数据的 PartyLocalEndpoint::SendMessage() 方法的地方,因为让一台设备能够以某种方式从另一台远程设备的源端点传输数据是没有意义的。
使用 C++ PlayFab Party 接口(推荐)时,对象作为 C++ 类实例公开。使用平面 C 接口时,对象由句柄值表示。
更详细地介绍所有主要对象的角色
- 管理器(
PartyManager) - 网络(
PartyNetwork) - 设备(
PartyDevice和PartyLocalDevice) - 用户(用户实体 ID 和
PartyLocalUser) - 端点(
PartyEndpoint和PartyLocalEndpoint) - 聊天控件(
PartyChatControl和PartyLocalChatControl) - 状态变更(
PartyStateChange)
管理器
除了前面总结的对象之外,PlayFab Party API 还公开了一个顶层的PartyManager 单例对象。
此实用工具/组织对象在很大程度上用作开始使用其他对象的起点。例如,新的网络和本地用户最初都在管理器中创建。所有异步操作完成和通知也集中在这里。最基本的是,管理器是在使用之前初始化 PlayFab Party 库以及在不再需要时清理该库的地方。
网络
PartyNetwork 对象表示一个安全的参与设备、其授权用户以及任何伴随的端点或聊天控件集合。 网络 最初创建时为空,但设备连接到它们并将至少一个本地用户验证到 网络 中。没有任何已验证用户的 网络 会在超时后自动销毁。
为了连接到它们, 网络 使用 网络描述符 进行引用。 网络描述符 主要是包含 PlayFab Party 内部识别和定位 网络 所需信息的不透明二进制结构。API 提供了将结构序列化为 Web 服务友好字符串以及反序列化的方法,以便可以使用常见的社交平台邀请机制、PlayFab Matchmaking 或其他 PlayFab Party 本身范围之外的外部会合机制与其他设备交换。
网络 的 网络描述符 在极少情况下可能会更改。游戏应准备好接收此类更改的通知,并随后为现有 网络 更新或重新广告新的 网络描述符,以避免其他设备连接时出现问题。
PartyNetwork 对象执行的操作包括:向其中验证本地用户、连接和枚举聊天控件、创建和枚举端点,或获取 网络 范围的性能信息。
设备
PartyDevice 对象代表在物理设备上执行的游戏及其 PlayFab Party 库代码的独立实例。大多数操作并不直接对 PartyDevice 对象本身执行;相反,它们是一种组织机制,用于定义哪些端点或聊天控件属于该游戏实例,特别是对于支持多个本地用户同时使用的平台和游戏。例如,PlayFab Party 使用此关系知识来优化游戏数据和聊天的传输,即使设备上的多个目标需要接收消息,也只发送该消息的一个副本。
远程 PartyDevice 对象是连接到网络并将用户验证到该网络的“副产品”。它们仅在与本地 设备 也已连接到的网络中参与的、与该 设备 关联的有效已验证远程用户存在时才被创建。相应地,一旦这不再成立,它们也会被销毁。
另一方面,只要 PlayFab Party 处于已初始化状态,本地游戏实例始终可以引用专门的子对象 PartyLocalDevice。它永远不会被显式地创建或销毁。
用户
PlayFab Party 用户 是一个独特的人类玩家,游戏为其执行 PlayFab 玩家登录 以获取title_player_account 实体 ID 和令牌。
远程用户在 PlayFab Party API 中仅通过其与聊天控件以及(可选地)与端点关联的实体 ID 字符串来标识。它们不使用专用对象表示。这是因为除了原始识别和作为与那些其他对象关联的标签之外,PlayFab Party 没有与任意用户以有意义的方式交互的功能。
相反,对于本地 用户,存在显式的 PartyLocalUser 对象,因为游戏在 PlayFab Party 内拥有其生命周期管理。游戏通常会在使用适用的登录方法成功登录该 PlayFab 玩家时创建 PartyLocalUser,并在该用户注销时适当地销毁 PartyLocalUser。对于支持多个本地玩家登录的平台和游戏,应为每位玩家创建额外的 PartyLocalUser 对象。
PartyLocalUser 对象也很重要,因为它们是所有身份验证的基础。要么创建新的网络,要么向网络进行身份验证,都必须存在有效的本地 用户。
授权用户在主题邀请和安全模型中有更详细的描述。
几乎每个操作都需要提供或存在 PartyLocalUser,尽管很少有操作直接在 PartyLocalUser 对象本身上执行。
PartyLocalUser 对象使用 PartyManager 对象创建。它们只能由其创建者显式销毁。虽然它们在远程设备上没有直接的对象表示,但如果拥有设备移除 PartyLocalUser 或断开与网络的连接(无论是正常还是异常),与其关联的聊天控件和端点将被销毁。
端点
PartyEndpoint 对象是可选的,但对于利用它们的游戏来说,它们是 PlayFab Party 数据通信的核心。与典型的网络套接字类似, 端点 是在网络内发起或定向数据消息的抽象寻址机制。它们可以代表一个设备、单个用户或任何你希望唯一标识以发送和接收消息的任意游戏定义概念(例如,一个坦克单位)。
专门的 PartyLocalEndpoint 子对象用于本地游戏实例在网络中创建的 端点。大部分 端点 功能都位于此处。其 PartyLocalEndpoint::SendMessage() 将游戏数据负载从 PartyLocalEndpoint 传输到同一网络中的一个或多个其他 PartyEndpoint 对象。它提供了各种选项,用于选择如何最好地处理 Internet 数据包丢失(例如,保证传输和/或排序)、在低延迟与合并来自同一或其他本地端点的多个消息以降低带宽使用之间控制权衡,以及在连接质量不足以支持游戏发送速率时做出反应。
除了自己是数据消息的源或目标之外,每个 PartyEndpoint 对象还由 PlayFab Party 分配一个 16 位 端点唯一标识符,允许你在发送到网络内单独 PartyEndpoint 对象或从其发送的消息负载中引用特定的 端点。例如,这提供了一种便捷的方式,可避免发送完整的、较大的用户实体 ID 字符串或其可能表示的其他标识符的开销,而无需构建自己的点对点身份协议协商。
PartyLocalEndpoint 对象使用其所包含的 PartyNetwork 对象创建。这样做会导致在远程设备上创建相应的 PartyEndpoint 对象。 端点 可以由其创建者显式销毁,或者当拥有设备与网络断开连接,或关联的 PartyLocalUser 对象(如果指定了)从网络中移除时,被隐式销毁。
聊天控件
PartyChatControl 对象是用于使用 PlayFab Party 可选聊天通信功能的机制。它们表示特定用户的关联音频输入/输出设备、偏好设置和通信策略。
专门的 PartyLocalChatControl 子对象也可用于本地游戏实例创建的 聊天控件。例如,你在此处配置允许与远程 PartyChatControl 对象进行聊天通信的权限,以选择全网络与仅团队聊天,或应用平台策略限制。本地 聊天控件 用于发送聊天文字、将文字合成为语音、请求语音流的转录和翻译、静音等。
PartyLocalChatControl 对象必须先连接到网络,然后才会在同一网络中的远程设备上创建为 PartyChatControl 对象。即使设备和 聊天控件 共同连接到多个网络,设备也始终仅看到创建的一个代表性 PartyChatControl 对象。这有助于避免不必要地重复或中断音频和文字聊天消息。
PartyLocalChatControl 对象使用所包含的 PartyLocalDevice 对象创建。 聊天控件 可以由其创建者显式销毁,或者当拥有设备与网络断开连接,或关联的 PartyLocalUser 对象从网络中移除时,被隐式销毁。
状态变更
PartyStateChange 结构用于向游戏通知所有异步操作完成、传入消息、更新通知以及其他与 API 相关的事件。
为了简化你处理具有不可预测时序的、通过 Internet 进行的复杂多机交互的方式,PlayFab Party 保证除非游戏显式调用,否则不会修改它从 API 报告的任何状态。但由于你仍需要一种方式来了解修改本地状态的远程发起的操作或计划外事件,PlayFab Party 和游戏通过一对特殊方法 PartyManager::StartProcessingStateChanges() 和 PartyManager::FinishProcessingStateChanges() 进行协作。这些方法在游戏工作循环的一个便于处理此类更新的地方调用。新事件从 PartyManager::StartProcessingStateChanges() 作为零个或多个 PartyStateChange 结构的数组报告。一旦游戏处理完 状态变更,便使用 PartyManager::FinishProcessingStateChanges() 返回该数组。
PartyStateChange 结构本身不是一个完整的对象。它是一个基础头部,将被强制转换为一个更详细的结构,其中包含关于特定完成或通知类型的信息、相关对象的指针以及任何错误信息。
后续主题将详细描述如何处理 状态变更。
后续步骤
- 了解 PlayFab Party 邀请和安全模型
- 了解 PlayFab Party 如何与你的发现流程交互
- 详细了解 PlayFab Party 聊天通信
- 了解如何处理 PlayFab Party 中的异步操作和通知
