

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

# 为 Amazon GameLift Servers 构建后端服务
构建后端服务

我们建议您实施游戏客户端服务，对您的玩家进行身份验证并与 Amazon GameLift Servers API 进行通信。通过实现自定义游戏客户端服务，您可以：
+ 自定义玩家身份验证。
+ 管控 Amazon GameLift Servers 将玩家加入新建游戏会话或接入既有游戏会话的分组规则。
+ 从自有资源采集玩家技能等级等属性数据用于对站匹配，避免直接采信客户端数据。

使用游戏客户端服务还可以降低游戏客户端直接与您的 Amazon GameLift Servers API 交互所带来的安全风险。

## 对您的玩家进行身份验证


您可以使用 Amazon Cognito 和玩家会话 IDs 对您的游戏客户端进行身份验证。要管理玩家身份的生命周期和属性，请使用 Amazon Cognito 用户群体。

如果您愿意，可以构建自定义身份解决方案并将其托管在 AWS。您还可以使用 Lambda 授权方通过 API Gateway 进行自定义授权逻辑。

**其他资源**
+ [使用身份池（联合身份）](https://docs.aws.amazon.com/cognito/latest/developerguide/identity-pools.html)（Amazon Cognito 开发人员指南）
+ [用户群体入门](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-user-pools.html)（Amazon Cognito 开发人员指南）
+ [如何使用 Amazon Cognito 设置玩家身份验证](https://aws.amazon.com/blogs/gametech/how-to-set-up-player-authentication-with-amazon-cognito/)（AWS 适用于游戏博客）

# 集成 Amazon GameLift Servers 游戏客户端功能
集成游戏客户端功能

将 Amazon GameLift Servers 游戏托管功能集成到需要与 Amazon GameLift Servers 服务通信的任何解决方案组件中，例如获取游戏会话信息或创建新的游戏会话。在大多数情况下，此功能内置在后端服务组件中。为核心任务添加功能，包括：
+ 请求活动游戏会话的信息和状态。
+ 在现有游戏会话中为新玩家预留位置。
+ 为一组玩家创建新的游戏会话。
+ 请求一个或多个玩家的对战。
+ 为现有游戏会话提供更新数据。

[与游戏 client/server 互动 Amazon GameLift Servers](gamelift-sdk-interactions.md)有关游戏托管组件如何通过进行交互的更多详细信息，请参阅Amazon GameLift Servers SDKs。

## 设置 Amazon GameLift Servers API


将 w 适用于 C\$1\$1 的 AWS SDK it Amazon GameLift Servers h 添加到项目中。

添加代码以初始化 Amazon GameLift Servers 客户端并存储键设置。此代码必须在依赖于 Amazon GameLift Servers 的任何代码之前运行。

1. 设置客户端配置。使用默认客户端配置或创建自定义客户端配置对象。有关更多信息，请参阅 [https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-core/html/struct_aws_1_1_client_1_1_client_configuration.html](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-core/html/struct_aws_1_1_client_1_1_client_configuration.html)(C\$1\$1) 或 [AmazonGameLiftConfig](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/GameLift/TGameLiftConfig.html)(C\$1)。

   客户端配置指定了联系 Amazon GameLift Servers 时要使用的目标区域和端点。区域确定要使用的已部署资源集（实例集、队列和对战）。默认客户端配置设置位置为美国东部（弗吉尼亚州北部）区域。要使用任何其他区域，请创建自定义配置。

1. 初始化 Amazon GameLift Servers 客户端。将 [Aws:GameLift:: GameLiftClient ()](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-gamelift/html/class_aws_1_1_game_lift_1_1_game_lift_client.html) (C\$1\$1) 或 [AmazonGameLiftClient()](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/GameLift/TGameLiftClient.html) (C\$1) 与默认客户端配置或自定义客户端配置一起使用。

1. 如果您使用玩家会话功能，需添加为每个玩家生成一个唯一标识符的机制。有关更多信息，请参阅 [生成玩家 ID](player-sessions-player-identifiers.md)。

1. 收集并存储以下信息：
   + **目标实例集**：如果您在特定实例集上手动创建游戏会话，请提供实例集 ID 或指向目标实例集的别名 ID。如果实例集属于多位置，请指定一个实例集位置。最佳做法是使用实例集别名，这样您就可以在不更新后端服务的情况下将玩家从一个实例集切换到另一个实例集。
   + **目标实例集**：对于使用多实例集队列放置新游戏会话的游戏，请指定用于发送放置请求的队列的名称。
   + **AWS 凭证** — 所有对的调用都Amazon GameLift Servers必须提供托管游戏的凭据。 AWS 账户 您可以通过创建玩家用户来获取这些凭证，如[为游戏设置编程式访问权限](setting-up-aws-login.md#getting-started-iam-player-user)中所述。根据您管理玩家用户访问权限的方式，请执行以下操作：
     + 如果您使用角色来管理玩家用户权限，请在调用 Amazon GameLift Servers API 之前添加代入该角色的代码。承担角色的请求返回一组临时安全凭证。有关更多信息，请参阅 [IAM *用户指南中的切换到 IAM* 角色 (AWS API)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-api.html)。
     + 如果您拥有长期安全凭证，请配置您的代码以查找和使用存储的凭证。请参阅《工具参考指南》*AWS SDKs 和《工具参考指南*》中的[使用长期凭证进行身份验证](https://docs.aws.amazon.com/sdkref/latest/guide/access-iam-users.html)。有关存储凭据的信息，请参阅 [(C\$1\$1) 和 [(.NET)](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html)](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-core/html/class_aws_1_1_auth_1_1_a_w_s_credentials.html) 的AWS API 参考。
     + 如果您有临时安全证书，请使用 AWS Security Token Service (AWS STS) 添加代码以定期刷新证书，如 *IAM 用户指南 AWS SDKs*[中的使用临时安全证书](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html#using-temp-creds-sdk)中所述。该代码必须在旧凭证过期之前请求新的凭证。

## 获取活动的游戏会话


添加用于发现可用游戏会话和管理游戏会话设置和元数据的代码。

**搜索活动的游戏会话。**

[SearchGameSessions](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_SearchGameSessions.html)用于获取有关特定游戏会话、所有活跃会话或符合一组搜索条件的会话的信息。此调用会为每个活动游戏会话返回一个与您的搜索请求相匹配的[GameSession](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_GameSession.html)对象。此对象包含游戏客户端连接到游戏会话所需的 DNS 名称、IP 地址和端口。

使用搜索条件获取经筛选列表，列出可供玩家接入的活动游戏会话。例如，您可以按照以下方式筛选会话：
+ 排除已饱和的游戏会话：`CurrentPlayerSessionCount = MaximumPlayerSessionCount`
+ 根据会话运行的时长来选择游戏会话：评估 `CreationTime`
+ 根据自定义游戏属性查找游戏会话：`gameSessionProperties.gameMode = "brawl"`

**管理游戏会话数据**

使用以下任意一项操作来检索或更新游戏会话信息。
+ [DescribeGameSessionDetails()](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_DescribeGameSessionDetails.html) — 获取游戏会话的保护状态以及游戏会话信息。
+ [UpdateGameSession()](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_UpdateGameSession.html) — 根据需要更改游戏会话的元数据和设置。
+ [GetGameSessionLogUrl](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_GetGameSessionLogUrl.html)— 访问存储的游戏会话日志。

## 创建游戏会话


添加用于在已部署的实例集中启动新游戏会话并使其可供玩家接入的代码。创建游戏会话有两种选择，具体取决于游戏托管解决方案管理游戏会话放置的方式。

**通过多位置队列创建游戏会话**

[StartGameSessionPlacement](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_StartGameSessionPlacement.html)用于在队列中请求新游戏会话。要使用此操作，请创建一个队列。这决定了 Amazon GameLift Servers 将新游戏会话放置在哪里。有关队列及其使用方法的更多信息，请参阅 [配置游戏会话放置](queues-intro.md)。

创建游戏会话放置时，指定要使用的队列名称、游戏会话名称、最大并发玩家数量以及一组可选的游戏属性。您可以选择提供玩家列表来自动加入游戏会话。如果您为相关区域包括玩家延迟数据，Amazon GameLift Servers 会使用此信息将新游戏会话放置到能够为玩家提供尽可能最佳玩游戏体验的实例集上。

要获得准确的延迟测量值，请使用 Amazon GameLift Servers 的 UDP ping 信标。这些端点使您能够测量玩家设备与潜在托管位置之间的实际 UDP 网络延迟，从而比使用 ICMP ping 更准确地做出放置决策。有关使用 UDP ping 信标测量延迟的更多信息，请参阅 [UDP ping 信标](reference-udp-ping-beacons.md)。

游戏会话放置为异步操作。在放置请求后，您等待其成功或超时。您也可以随时使用取消请求[StopGameSessionPlacement](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_StopGameSessionPlacement.html)。要查看您的安置申请的状态，请致电[DescribeGameSessionPlacement](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_DescribeGameSessionPlacement.html)。

**在特定的实例集中创建游戏会话。**

[CreateGameSession](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_CreateGameSession.html)用于在指定队列上创建新会话。这一同步操作成功与否取决于该实例集是否拥有托管新游戏会话所需的资源。在Amazon GameLift Servers创建新的游戏会话并返回[GameSession](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_GameSession.html)对象后，你可以加入玩家的行列。

使用此操作时，请提供实例集 ID 或别名 ID、会话名称和游戏中的最大并发玩家数量。您可以选择包括一组游戏属性。游戏属性是在键值对的数组中定义的。

如果您使用 Amazon GameLift Servers 的资源保护功能来限制一个玩家可创建的游戏会话数量，则需指定游戏会话创建者的玩家 ID。

## 将玩家接入游戏会话


添加在活动的游戏会话中预留玩家位置以及将游戏客户端连接到游戏会话的代码。如果您的游戏使用与唯一玩家的玩家会话，则可以使用此操作 IDs。有关玩家会话的更多信息，请参阅[Amazon GameLift Servers 和玩家体验](game-sessions-intro.md)。

1. 

**在游戏会话中预留玩家位置。**

   要预留玩家位置，请在游戏会话中创建一个玩家会话。有两种方式可执行此操作：
   + 如果您使用[StartGameSessionPlacement](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_StartGameSessionPlacement.html)或[ StartMatchmaking](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_StartMatchmaking.html)创建游戏会话，则可以在请求中包含一个或多个玩家，以便在新游戏会话中为他们创建玩家会话。
   + 要将玩家添加到现有游戏会话中，请致电[CreatePlayerSession](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_CreatePlayerSession.html)或[CreatePlayerSessions](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_CreatePlayerSessions.html)提供游戏会话 ID。

   玩家会话请求必须包括唯一的玩家 ID。有关更多信息，请参阅 [生成玩家 ID](player-sessions-player-identifiers.md)。Amazon GameLift Servers 接收到该请求后，会先验证该游戏会话是否接受新玩家，以及是否有可用的玩家位置。如果成功，则为玩家Amazon GameLift Servers保留一个位置，创建新的玩家会话并返回一个[PlayerSession](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_PlayerSession.html)对象。

   玩家会话可能包括一组自定义玩家数据。此数据存储在新建的玩家会话对象中。当玩家直接连接到游戏会话时，Amazon GameLift Servers 会将此对象传递到游戏服务器。如果请求创建多个玩家会话，需将每段玩家数据字符串映射至相应的玩家 ID。

1. 

**连接游戏会话**

   向后端服务添加代码以检索`PlayerSession`对象（例如通过调用 [DescribePlayerSessions()](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_DescribePlayerSessions.html)）并将其传递回游戏客户端。此对象包含 DNS 名称、IP 地址和端口。游戏客户端可使用此信息与服务器建立直接连接。
   + 您可以使用指定的端口以及分配给服务器进程的 DNS 名称或 IP 地址进行连接。
   + 如果实例集启用了 TLS 证书生成，则必须使用 DNS 名称和端口进行连接。
   + 如果您的游戏服务器验证了传入的玩家连接，请引用玩家会话 ID。

   建立连接后，游戏客户端和服务器进程可直接通信，不需要经过 Amazon GameLift Servers。服务器与 Amazon GameLift Servers 保持通信，以报告玩家连接状态、运行状况等。

   如果游戏服务器验证了传入的玩家，则它会验证玩家会话 ID 是否与游戏会话中的预留位置相匹配，然后接受或拒绝玩家连接。当玩家断开连接时，服务器进程报告断开连接。

## 将自定义游戏数据传入游戏会话


游戏客户端可以将数据传入游戏会话。创建游戏会话时，您可以在请求中包含一组游戏属性（键值对）或游戏会话数据（字符串值）。您还可以使用新的或更新的游戏数据更新现有游戏会话。这些数据将传入托管游戏会话的游戏服务器进程，供游戏服务器代码使用。您无法删除游戏属性。

例如，假设您的游戏定义了四个难度等级：`Novice`、`Easy`、`Intermediate` 和 `Expert`。当玩家选择加入 `Easy` 难度的游戏时，您的游戏客户端会通过后端服务请求创建新游戏会话，并附带以下游戏属性：`{"Key": "Difficulty", "Value":"Easy"}`。作为响应，Amazon GameLift Servers 会提示可用的游戏服务器启动新的游戏会话并传递 `GameSession` 对象。随后，游戏服务器进程会使用提供的游戏属性来设置游戏会话的难度等级。

### 了解详情

+ [GameProperty 数据类型](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_GameProperty.html) 
+ [SearchGameSessions() 示例](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_SearchGameSessions.html#API_SearchGameSessions_Examples) 
+ [UpdateGameSession() GameProperties 参数](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_UpdateGameSession.html#gamelift-UpdateGameSession-request-GameProperties) 

# 带有无服务器后端的独立游戏会话服务器
无服务器后端

使用无服务器客户端服务架构，后端可以从高度可扩展的数据库中查看对战票证的状态，而不必直接访问 Amazon GameLift Servers API。

下图显示了构建的无服务器后端 AWS 服务 ，该后端可以将玩家匹配到在Amazon GameLift Servers舰队上运行的游戏。下表提供了对每个带编号的注解的说明。要尝试此示例，请参阅开启的[基于多人会话的游戏托管。 AWS](https://github.com/aws-samples/aws-gamelift-and-serverless-backend-sample) GitHub

![\[无服务器架构示例，可将玩家匹配到在 Amazon GameLift Servers 实例集上运行的游戏。\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/qs_arch_serverless.png)


1. 游戏客户端从 Amazon Cognito 身份池中请求 Amazon Cognito 用户身份。

1. 游戏客户端接收临时访问凭证，并通过 Amazon API Gateway API 请求游戏会话。

1. API Gateway 调用一个函数。 AWS Lambda 

1. Lambda 函数从 Amazon DynamoDB NoSQL 表中请求玩家数据。该函数在请求上下文数据中提供 Amazon Cognito 身份。

1. Lambda 函数通过 Amazon GameLift Servers FlexMatch 对战请求匹配。

1. FlexMatch匹配一组具有适当延迟的玩家，然后通过Amazon GameLift Servers队列请求游戏会话放置。队列中有包含一个或多个 AWS 区域 地点的舰队。

1. Amazon GameLift Servers 将会话放到其中一个实例集的位置后，Amazon GameLift Servers 向 Amazon Simple Notification Service（Amazon SNS）主题发送一个事件通知。

1. Lambda 函数接收并处理 Amazon SNS 事件。

1. 如果对战票证是一个 `MatchmakingSucceeded` 事件，那么 Lambda 函数会将结果以及游戏服务器的端口和 IP 地址写入 DynamoDB 表。

1. 游戏客户端向 API Gateway 发出签名请求，以查看特定时间间隔内的对战票证状态。

1. API Gateway 使用 Lambda 函数来检查对战票证状态。

1. Lambda 函数会检查 DynamoDB 表以查看票证是否成功。如果成功，该函数会将游戏服务器的端口和 IP 地址以及玩家会话 ID 发送回客户端。如果票证未成功，则该函数会发送响应，确认匹配尚未准备就绪。

1. 游戏客户端使用后端服务提供的端口和 IP 地址，使用 TCP 或 UDP 连接到游戏服务器。然后，游戏客户端将玩家会话 ID 发送到游戏服务器，然后游戏服务器使用 Amazon GameLift Servers 服务器软件开发工具包验证该 ID。

# 带有 WebSocket基于后端的独立游戏会话服务器
WebSocket基于后端

使用 WebSocket基于 Amazon API Gateway 的架构，您可以使用服务器启动的消息向发出配对请求 WebSockets 并发送推送通知以完成配对。此架构通过在客户端和服务器之间进行双向通信来提高性能。

有关使用 API Gateway 的更多信息 WebSock APIs，[请参阅使用 WebSocket APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html)。

下图显示了一种 WebSocket基于后端的架构，该架构使用 API Gateway 等将玩家匹配 AWS 服务 到在Amazon GameLift Servers舰队上运行的游戏。下表提供了对每个带编号的注解的说明。

![\[将玩家匹配到在Amazon GameLift Servers舰队上运行的游戏的 WebSockets 架构示例。\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/qs_arch_websockets.png)


1. 游戏客户端从 Amazon Cognito 身份池中请求 Amazon Cognito 用户身份。

1. 游戏客户端使用亚马逊 Cognito 凭证签署与 API Gateway API 的 WebSocket 连接。

1. API Gateway 在连接上调 AWS Lambda 用一个函数。该函数将连接信息存储在 Amazon DynamoDB 表中。

1. 游戏客户端通过 API Gateway API 通过 WebSocket 连接向 Lambda 函数发送一条消息，请求会话。

1. Lambda 函数通过 Amazon GameLift Servers FlexMatch 对战接收消息并请求匹配。

1. FlexMatch匹配一组玩家后，通过Amazon GameLift Servers队列FlexMatch请求游戏会话放置。

1. Amazon GameLift Servers 将会话放到其中一个实例集的位置后，Amazon GameLift Servers 向 Amazon Simple Notification Service（Amazon SNS）主题发送一个事件通知。

1. Lambda 函数接收并处理 Amazon SNS 事件。

1. 如果对战票证是 `MatchmakingSucceeded` 事件，那么 Lambda 函数会向 DynamoDB 请求正确的玩家连接。然后，该函数通过 WebSocket 连接通过 API Gateway API 向游戏客户端发送一条消息。在这种架构中，游戏客户端不会主动轮询对战状态。

1. 游戏客户端通过 WebSocket 连接接收游戏服务器的端口和 IP 地址以及玩家会话 ID。

1. 游戏客户端使用后端服务提供的端口和 IP 地址，使用 TCP 或 UDP 连接到游戏服务器。游戏客户端还将玩家会话 ID 发送到游戏服务器，然后游戏服务器使用 Amazon GameLift Servers 服务器软件开发工具包验证该 ID。