Amazon GameLift
开发人员指南 (版本 )
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

集成 实时服务器 的游戏客户端

本主题介绍如何准备您的游戏客户端以便能够加入并参与 Amazon GameLift 托管的游戏会话。

准备游戏客户端需要两组任务:

  • 设置您的游戏客户端以获取有关现有游戏的信息、请求对战、启动新游戏会话以及为玩家预留游戏会话位置。

  • 使您的游戏客户端能够加入Realtime服务器上托管的游戏会话并交换消息。

查找或创建游戏会话和玩家会话

设置您的游戏客户端以查找或启动游戏会话、请求 FlexMatch 对战以及通过创建玩家会话为游戏中的玩家预留空间。作为最佳实践,请创建一个客户端服务,在某个游戏客户端操作触发该服务时使用它直接向 Amazon GameLift 服务发出请求。然后,客户端服务会将相关响应中继回游戏客户端。

  1. 将 AWS 软件开发工具包添加到您的客户端服务项目,初始化 Amazon GameLift 客户端,并将其配置为使用您的队组和/或队列中的托管资源。该 AWS SDK提供多种语言;请参阅对于客户端服务的 Amazon GameLift 开发工具包。

  2. 将 GameLift 功能添加到您的客户端服务。有关更详细的说明,请参阅将 Amazon GameLift 添加到游戏客户端添加 FlexMatch 对战。最佳做法是使用游戏会话放置功能来创建新的游戏会话。此方法可让您充分利用 GameLift 快速而智能地放置新游戏会话的功能,并且可以利用玩家延迟数据来最大程度地减少游戏延迟。至少,您的客户端服务必须能够请求新的游戏会话,并处理响应中的游戏会话数据。您还可能需要添加功能,以搜索并获取现有游戏会话的信息和请求玩家会话,这会有效地保留现有游戏会话中的玩家位置。

  3. 将连接信息传回游戏客户端。后端游戏服务接收游戏会话和玩家会话对象,以响应对 Amazon GameLift 服务的请求。这些对象包含游戏客户端直接连接到运行在 Realtime Server 上的游戏会话所需的信息,尤其是连接详细信息(IP 地址和端口)以及玩家会话 ID。

连接到 实时服务器 上的游戏

使您的游戏客户端能够与Realtime服务器上托管的游戏会话直接连接并与服务器和其他玩家交换消息。

  1. 获取Realtime客户端软件开发工具包,构建它,并将其添加到您的游戏客户端项目。有关软件开发工具包要求的更多信息以及如何生成客户端库的说明,请参阅自述文件。

  2. 将以下功能添加到您的游戏客户端。有关更多信息,请参阅实时服务器 客户端 API (C#) 参考

  3. 根据需要设置客户端回调的事件处理程序。请参阅 实时服务器 客户端 API (C#) 参考:异步回调

游戏客户端示例

基本 Realtime 客户端 (C #)

此示例说明与Realtime客户端软件开发工具包 (C#) 的基本游戏客户端集成。如下所示,该示例初始化Realtime客户端对象,设置事件处理程序并实施客户端回调,连接到Realtime服务器,发送消息,然后断开连接。

using System; using System.Text; using Aws.GameLift.Realtime; using Aws.GameLift.Realtime.Event; using Aws.GameLift.Realtime.Types; namespace Example { /** * An example client that wraps the GameLift Realtime client SDK * * You can redirect logging from the SDK by setting up the LogHandler as such: * ClientLogger.LogHandler = (x) => Console.WriteLine(x); * */ class RealTimeClient { public Aws.GameLift.Realtime.Client Client { get; private set; } public bool OnCloseReceived { get; private set; } // An opcode defined by client and your server script that represents a custom message type private const int MY_TEST_OP_CODE = 10; /// <summary> /// Initialize a client for GameLift Realtime and connects to a player session. /// </summary> /// <param name="endpoint">The endpoint for the GameLift Realtime server to connect to</param> /// <param name="tcpPort">The TCP port for the GameLift Realtime server</param> /// <param name="localUdpPort">Local Udp listen port to use</param> /// <param name="playerSessionId">The player session Id in use - from CreatePlayerSession</param> /// <param name="connectionPayload"></param> public RealTimeClient(string endpoint, int tcpPort, int localUdpPort, string playerSessionId, byte[] connectionPayload) { this.OnCloseReceived = false; ClientConfiguration clientConfiguration = ClientConfiguration.Default(); Client = new Aws.GameLift.Realtime.Client(clientConfiguration); Client.ConnectionOpen += new EventHandler(OnOpenEvent); Client.ConnectionClose += new EventHandler(OnCloseEvent); Client.GroupMembershipUpdated += new EventHandler<GroupMembershipEventArgs>(OnGroupMembershipUpdate); Client.DataReceived += new EventHandler<DataReceivedEventArgs>(OnDataReceived); ConnectionToken token = new ConnectionToken(playerSessionId, connectionPayload); Client.Connect(endpoint, tcpPort, localUdpPort, token); } public void Disconnect() { if (Client.Connected) { Client.Disconnect(); } } public bool IsConnected() { return Client.Connected; } /// <summary> /// Example of sending to a custom message to the server. /// /// Server could be replaced by known peer Id etc. /// </summary> /// <param name="intent">Choice of delivery intent ie Reliable, Fast etc. </param> /// <param name="payload">Custom payload to send with message</param> public void SendMessage(DeliveryIntent intent, string payload) { Client.SendMessage(Client.NewMessage(MY_TEST_OP_CODE) .WithDeliveryIntent(intent) .WithTargetPlayer(Constants.PLAYER_ID_SERVER) .WithPayload(StringToBytes(payload))); } /** * Handle connection open events */ public void OnOpenEvent(object sender, EventArgs e) { } /** * Handle connection close events */ public void OnCloseEvent(object sender, EventArgs e) { OnCloseReceived = true; } /** * Handle Group membership update events */ public void OnGroupMembershipUpdate(object sender, GroupMembershipEventArgs e) { } /** * Handle data received from the Realtime server */ public virtual void OnDataReceived(object sender, DataReceivedEventArgs e) { switch (e.OpCode) { // handle message based on OpCode default: break; } } /** * Helper method to simplify task of sending/receiving payloads. */ public static byte[] StringToBytes(string str) { return Encoding.UTF8.GetBytes(str); } /** * Helper method to simplify task of sending/receiving payloads. */ public static string BytesToString(byte[] bytes) { return Encoding.UTF8.GetString(bytes); } } }