

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 将 FlexMatch 添加到游戏客户端
<a name="match-client"></a>

本主题介绍如何将 FlexMatch 对战功能添加到您的客户端游戏组件。

我们强烈建议您的游戏客户端通过后端游戏服务发起对战请求。通过使用此可信源与 Amazon GameLift Servers 服务通信，您可以更轻松地防范黑客攻击和虚假玩家数据。如果您的游戏具有会话目录服务，那么这是一个用于处理对战请求的好选项。无论将 FlexMatch 与 Amazon GameLift Servers 托管服务配合使用，还是作为独立服务使用，通过后端游戏服务统一调用 Amazon GameLift Servers 服务均为最佳实践。

无论您是将 FlexMatch 与 Amazon GameLift Servers 托管式通过配合使用，还是作为独立服务与其他托管解决方案搭配使用，均需进行客户端更新。使用作为 AWS SDK 一部分的服务 API 添加以下功能：Amazon GameLift Servers
+ 请求一个或多个玩家的对战（必需）。根据您的对战规则集，此请求可能需要某些特定于玩家的数据，包括玩家属性和延迟。
+ 跟踪对战请求的状态（必需）。通常，此任务需要设置事件通知。
+ 要求玩家接受建议的对战游戏。此功能需要与玩家进行额外互动，才能显示对战详情并允许他们接受或拒绝对战。
+ 获取游戏会话连接信息，并加入游戏（必需）。在新对战的游戏会话开始后，检索游戏会话的连接信息，然后使用它来连接游戏会话。

## 客户端必备任务
<a name="match-client-setup"></a>

在向游戏添加客户端功能之前，您需要完成以下任务：
+ **将 AWS SDK 添加到您的后端服务。**该后端服务需使用 Amazon GameLift Servers API 中的功能，它是 AWS 软件开发工具包的一部分。要了解有关 AWS SDK 的更多信息并下载最新版本，请参Amazon GameLift Servers SDKs 阅 “[客户服务](https://docs.aws.amazon.com/gamelift/latest/developerguide/gamelift-supported.html#gamelift-supported-clients)”。有关 API 的描述和功能，请参阅[Amazon GameLift ServersFlexMatchAPI 参考 (AWS SDK)](reference-awssdk-flex.md)。
+ **设置对战票证系统。**所有对战请求必须具有唯一票证 ID。创建一种机制来生成唯一的票证 IDs 并将其分配给匹配的请求。票证 ID 可以使用任意字符串格式，最多 128 个字符。
+ **收集有关您的对战构建器的信息。**从您的配对配置和规则集获取以下信息。
  + 对战配置资源的名称。
  + 玩家属性列表，在规则集中定义。
+ **检索玩家数据。**设置一种方法来获取每位玩家的相关数据，以将其包含在对战请求中。您需要玩家 ID 和玩家属性值。如果您的规则集有延迟规则，或者您想在放置游戏会话时使用延迟数据，请收集玩家可能进入游戏的每个地理位置的延迟数据。要获得准确的延迟测量值，请使用 Amazon GameLift Servers 的 UDP ping 信标。这些端点使您能够测量玩家设备与每个潜在托管位置之间的实际 UDP 网络延迟，从而比使用 ICMP ping 更准确地做出放置决策。有关使用 UDP ping 信标测量延迟的更多信息，请参阅 [UDP ping 信标](https://docs.aws.amazon.com/gameliftservers/latest/developerguide/reference-udp-ping-beacons.html)。

# 请求玩家对战
<a name="match-client-start"></a>

将代码添加到您的游戏后端服务来管理对 FlexMatch 对战构建器的对战请求。对于使用 FlexMatch 和 Amazon GameLift Servers 托管的游戏，以及使用 FlexMatch 作为独立解决方案的游戏，申请 FlexMatch 对战的过程是相同的。

## 创建对战请求：
<a name="match-client-start-request"></a>

调用 Amazon GameLift Servers API [StartMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_StartMatchmaking.html)。每个请求都必须包含以下信息。

**对战构建器**  
要用于请求的对战配置的名称。FlexMatch 将各个请求放置到指定对战构建器的池中，并将根据对战构建器的配置方式来处理请求。这包括强制施加时间限制，是否请求玩家接受匹配，在放置生成的游戏会话时使用哪个队列，等等。在 [设计 FlexMatch 对战构建器](match-configuration.md) 中了解有关对战构建器和规则集的更多信息。

**票证 ID**  
分配给请求的唯一票证 ID。与请求相关的所有信息（包括事件和通知）都将引用票证 ID。

**玩家数据**  
您要为其创建对战的玩家的列表。如果根据对战规则和延迟最低值，请求中的任意玩家不满足对战要求，则对战请求绝不会生成成功的对战。您可在一个对战请求中包括最多十位玩家。当一个请求中有多个玩家时，FlexMatch 尝试创建单个对战并将所有玩家分配到相同团队中（随机选择）。如果请求包含的玩家数太多，无法放在一个对战团队中，则对战请求失败。例如，如果您设置了对战构建器，以创建 2 对 2 对战（两个团队，每个团队两个玩家），您无法发送包含两个以上玩家的对战请求。  
一个玩家 (通过其玩家 ID 标识) 一次只能包括在一个有效对战请求中。在您为玩家创建新请求时，将自动取消任何具有相同玩家 ID 的有效对战票证。
对于每个列出的玩家，请提供以下数据：  
+ *玩家 ID * – 每个玩家必须具有一个唯一的玩家 ID，该 ID 由您生成。参见[生成玩家 IDs](https://docs.aws.amazon.com/gamelift/latest/developerguide/player-sessions-player-identifiers.html)。
**重要**  
如果您创建的新对战请求包含已存在于现有有效对战请求中的玩家 ID，则现有请求将被自动取消。但是，系统不会为被取消的请求发送 `MatchmakingCancelled` 事件。要监控现有配对请求的状态，请使用[DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html)以不频繁的间隔（30-60 秒）轮询请求状态。被取消的请求将显示状态为 `CANCELLED`，原因标记为 `Cancelled due to duplicate player`。
+ *玩家属性* – 如果所使用的对战构建器需要玩家属性，请求必须为每个玩家提供这些属性。必需的玩家属性在对战构建器的规则集中定义，同时还会指定属性的数据类型。玩家属性仅在规则集指定属性的默认值时是可选的。如果对战请求未提供所有玩家的必需玩家属性，对战请求可能永远无法成功。在[构建 FlexMatch 规则集](match-rulesets.md)和[FlexMatch 规则集示例](match-examples.md)中了解有关对战构建器规则集和玩家属性的更多信息。
+ *玩家延迟* – 如果所使用的对战构建器有玩家延迟规则，请求必须报告每个玩家的延迟。玩家延迟数据是显示每个玩家的一个或多个值的列表。它表示对战构建器的队列中各个区域的玩家体验的延迟。如果请求中未包含延迟值，玩家将无法匹配，请求将失败。要获得准确的延迟测量值，请使用 Amazon GameLift Servers 的 UDP ping 信标。这些端点使您能够测量玩家设备与潜在托管位置之间的实际 UDP 网络延迟，从而比使用 ICMP ping 更准确地做出放置决策。有关使用 UDP ping 信标测量延迟的更多信息，请参阅 [UDP ping 信标](https://docs.aws.amazon.com/gameliftservers/latest/developerguide/reference-udp-ping-beacons.html)。

## 检索对战请求详细信息
<a name="match-client-start-retrieve"></a>

发送匹配请求后，您可以使用请求的票证 ID 致电[DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html)查看请求详情。此调用将返回请求信息，包括当前状态。成功完成请求之后，票证还将包含游戏客户端连接到对战所需的信息。

## 取消对战请求
<a name="match-client-start-cancel"></a>

您可以随时使用请求的门票ID致电来取消[StopMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_StopMatchmaking.html)配对请求。

# 对战事件
<a name="match-client-track"></a>

设置通知，以跟踪 Amazon GameLift Servers 为对战过程发出的事件。您可以直接设置通知，也可以通过创建 SNS 主题或使用 Amazon EventBridge 来设置通知。有关设置通知的更多信息，请参阅[设置 FlexMatch 事件通知](match-notification.md)。设置通知之后，请在客户端服务上添加侦听器以检测事件并根据需要做出响应。

在经过相当长一段时间而未通知的情况下，最好定期轮询状态更新来作为通知的备用手段。为了最大限度地减少对对战性能的影响，请务必在提交对战票证后或最后一次收到通知后，等待至少 30 秒后再轮询。

使用请求的票证 ID 进行调用，即可检索[DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html)配对请求单，包括当前状态。我们建议轮询频率不要超过每 10 秒一次。此方法仅在低容量开发场景中使用。

**注意**  
在使用大量对战场景之前，您应该使用事件通知设置游戏，例如进行预生产负载测试。公开发布版中的所有游戏都应该使用通知，而不考虑容量。连续轮询方法仅适用于对战使用率较低的开发中的游戏。

# 要求玩家接受
<a name="match-client-accept"></a>

如果您使用的是开启了玩家接受的对战构建器，请将代码添加到您的客户端服务来管理玩家接受过程。对于使用 FlexMatch 和 Amazon GameLift Servers 托管式托管的游戏，以及使用 FlexMatch 作为独立解决方案的游戏，管理玩家接受度的过程是相同的。

**要求玩家接受建议的对战游戏：**

1. **检测建议的对战游戏何时需要玩家接受。**监控对战票证以检测状态更改为 `REQUIRES_ACCEPTANCE` 的情况。更改此状态会触发 FlexMatch 事件 `MatchmakingRequiresAcceptance`。

1. **从所有玩家获取接受信息。**创建一个机制，以在对战票证中向每个玩家呈现建议的对战游戏详细信息。玩家必须能够表明他们接受或拒绝建议的对战游戏。您可以通过致电来检索比赛详情[DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html)。在对战构建器撤消建议的对战游戏之前，玩家仅有有限的响应时间。

1. **向 FlexMatch 报告玩家响应。**[AcceptMatch](https://docs.aws.amazon.com/gamelift/latest/apireference/API_AcceptMatch.html)使用 “接受” 或 “拒绝” 来报告玩家的回应。对战请求中的所有玩家必须接受对战游戏才能继续。

1. **处理具有失败接受的票证。**当建议的对战游戏中的任何一个玩家拒绝对战游戏，或者未能在接受时限内响应时，请求失败。接受对战的玩家的票证将自动退还到票证池中。未接受对战的玩家的票证将变为“失败”状态，不再受理。对于有多名玩家的票证，如果票证中有任何玩家不接受对战，则整张票证失效。

# 连接到对战游戏
<a name="match-client-connect"></a>

将代码添加到您的客户端服务以处理已成功完成的对战（状态 `COMPLETED` 或事件 `MatchmakingSucceeded`）。这包括向游戏客户端通知对战游戏的玩家和传递连接信息。

对于使用 Amazon GameLift Servers 托管式托管资源的游戏，成功完成对战请求后，游戏会话连接信息将添加到对战票证中。致电检索已完成的配对门票 [DescribeMatchmaking](https://docs.aws.amazon.com/gamelift/latest/apireference/API_DescribeMatchmaking.html). 连接信息包括游戏会话的 IP 地址和端口，以及每个玩家 ID 的玩家会话 ID。参阅[GameSessionConnectionInfo](https://docs.aws.amazon.com/gamelift/latest/apireference/API_GameSessionConnectionInfo.html)了解更多信息。您的游戏客户端将使用此信息直接连接到托管对战的游戏会话。已对战的游戏会话的连接请求应该包含玩家会话 ID 和玩家 ID。此数据将关联的玩家与游戏会话的比赛数据（包括队伍分配）相关联（参见 [GameSession](https://docs.aws.amazon.com/gamelift/latest/apireference/API_GameSession.html)）。

对于使用其他托管解决方案（包括 Amazon GameLift Servers FleetIQ）的游戏，您必须建立一种机制，使对战玩家能够连接到相应的游戏会话。

# 示例 StartMatchmaking 请求
<a name="match-client-sample"></a>

这些代码段为多个不同的对战构建器生成对战请求。如文中所述，请求必须提供所使用的对战构建器需要的玩家属性（在对战构建器的规则集中定义）。提供的属性必须使用在规则集中定义的相同的数据类型：数字 (N) 或字符串 (S)。

```
# Uses matchmaker for two-team game mode based on player skill level
def start_matchmaking_for_cowboys_vs_aliens(config_name, ticket_id, player_id, skill, team):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill}
            },
            "PlayerId": player_id,
            "Team": team
        }],
        TicketId=ticket_id)

# Uses matchmaker for monster hunter game mode based on player skill level
def start_matchmaking_for_players_vs_monster(config_name, ticket_id, player_id, skill, is_monster):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill},
                "desiredSkillOfMonster": {"N": skill},
                "wantsToBeMonster": {"N": int(is_monster)}
            },
            "PlayerId": player_id
        }],
        TicketId=ticket_id)

# Uses matchmaker for brawler game mode with latency
def start_matchmaking_for_three_team_brawler(config_name, ticket_id, player_id, skill, role):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "skill": {"N": skill},
                "character": {"S": [role]},
            },
            "PlayerId": player_id,
            "LatencyInMs": { "us-west-2": 20}
        }],
        TicketId=ticket_id)

# Uses matchmaker for multiple game modes and maps based on player experience
def start_matchmaking_for_multi_map(config_name, ticket_id, player_id, skill, maps, modes):
    response = gamelift.start_matchmaking(
        ConfigurationName=config_name,
        Players=[{
            "PlayerAttributes": {
                "experience": {"N": skill},
                "gameMode": {"SL": modes},
                "mapPreference": {"SL": maps}
            },
            "PlayerId": player_id
        }],
        TicketId=ticket_id)
```