关于地区

Photon Cloud为您提供全球连接,以便在全球范围内实现低延迟游戏。

客户端的初始连接转到Photon Nameserver,它为客户端提供可用区域列表。 通常,客户端连接启用“最佳区域”选择,这将帮助客户端检测具有最低ping的区域并连接到它(见下文)。

每个区域与其他区域完全分开,由主服务器(用于配对)和游戏服务器(用于托管房间)组成。

连接到光子云区域

可用区域的完整列表如下。 在仪表板中,您可以定义哪些区域应该可供客户端使用。

最佳区域的考虑

“最佳区域”选项不具有确定性。 有时它可能是“随机的”,因为有时候/某种情况下会得到几乎没有变化或完全相同的ping计算。

从理论上讲,你可以发现:

  • 同一设备对您可选择的多个区域具有相同的完全ping值。所以您最终连接到同一个网络的客户端上设置了不同区域,造成区域选择会是随机的。
  • 不同的设备连接到同一个区域,有不同的Ping值(或者同一个设备的多次不同尝试)。

例如,在“us”和“usw”(或“ru”和“rue”)的设置下,您可以使用在线区域白名单来选择您想要连接或者排除的区域。

可用区域

Photon Cloud在全球多个地区拥有服务器,并分布在世界各地有多个托管中心。

每个光子云区域由“区域令牌”标识。

要通过客户端的“Connect”方法传递”region token”区域令牌,请调用

loadBalancingClient.ConnectToRegionMaster(regionString);

可用区域和令牌清单:

区域 位置 令牌
亚洲 新加坡 ASIA
澳大利亚 墨尔本 AU
加拿大,东部 蒙特利尔 CAE
中国大陆 上海 CN
欧洲 阿姆斯特丹 EU
印度 金奈 IN
日本 东京 JP
俄国 莫斯科 RU
俄罗斯东部 哈巴罗夫斯克 RUE
南美洲 圣保罗 SA
韩国 汉城 KR
美国,东部 华盛顿 US
美国,西部 圣荷西 USW

控制面板区域过滤

您可以直接从您账户的控制面板(仪表盘)过滤每个应用程序可用的Photon Cloud区域列表。

光子云区域设定截图
设定可用的光子云区域

转到仪表板,然后单击所选应用程序的“管理”,然后单击“编辑”。 您将找到一个输入字段,您可以在其中输入列入白名单的区域,如下所示:

  • 允许的列表应该是用分号分隔的区域标记字符串。 例如“eu; us”。
  • 区域令牌不区分大小写,并在此定义。
  • 未定义或无法识别的区域令牌将从列表中忽略。
  • 空(“”)或格式不正确的字符串(例如“;;”)表示空列表。
  • 空列表表示允许所有可用区域。

确认并保存后, GetRegions操作将只返回过滤的区域列表。 因此,客户端应该从该列表中选择任何可用的区域,但请考虑到仪表盘的更新可能需要10分钟左右的时间(根据网络情况而定)。

如何选择一个地区

如果连接到Photon Cloud CN地区,国内区域用户的延迟最低,非常简单的逻辑。

但是如果你有来自世界各地的用户呢?

您可以

  • a)让游戏客户端ping不同的Photon Cloud区域,并预先选择最好的ping,阅读我们在文章下方提供的操作方法
  • b)使用固定了区域的客户端版本,因此来自不同地区的用户连接到不同的Photon Cloud区域
  • c)让用户从游戏菜单中选择一个匹配区域。

或者,您可以d)让所有用户连接到相同的地区,如果您的游戏玩家可以接受更高的延迟时间,例如任何“不那么实时”的游戏。

所有Photon Cloud应用程序都可在所有可用区域工作,无需任何额外费用。 查看价格

Photon Cloud的仪表板可让您监控每个地区的游戏使用情况,轻松升级或降级您的订阅计划。 转到您的仪表盘

如何以最低延迟开始游戏

连接到最近的主服务器

光子不建议使用通用的区域主服务器地址与主服务器的直接连接方法。 而是使用SDK提供的方法连接到您正在使用的区域主机!

如果您知道您的客户端连接到的最接近的区域,则可以只连接到该区域。

loadBalancingClient.ConnectToRegionMaster("us");

对于其他平台,请从SDK列表中链接到相应的SDK和API 。

SDK将从名称服务器(NameServer)获取所请求区域的主服务器地址(上图“连接到Photon Cloud地区”中的数字1),然后自动将您连接到所选区域中的主服务器(上图“连接到Photon Cloud地区”中的数字2)。

如何在运行时选择一个区域

如果要在运行时选择区域 – 例如,通过向玩家显示可用区域列表并让其选择,则需要先连接到名称服务器。 然后,您可以向名称服务器查询当前可用的区域主服务器地址列表(上面代码范例中的“ConnectToRegionMaster”)。

当我们写“名称服务器”时,名称服务器实际上是在可用区域之间的地理位置负载平衡。 这样可以尽可能快地请求主服务器的地址。

C#客户端SDK

loadBalancingClient.ConnectToNameServer()

连接成功后,您可以获得可用区域的列表。

loadBalancingClient.OpGetRegions()

使用主服务器列表,您现在可以ping所有来可用区域查找最佳连接时间,以达到最低延迟的游戏时间,或者让玩家选择一个区域。

当您的客户端确定该区域时,连接到该区域的主服务器(图“连接到Photon Cloud地区”中的数字2)。

loadBalancingClient.ConnectToRegionMaster("us")

最后,加入或创建一个游戏的空间(图“连接到Photon Cloud地区”中的数字3)。

C++客户端SDK

1.确保您连接到Photon Cloud。 Photon Server不支持云区域

2.类Client的构造方法有两个可选参数。 最后一个,称为regionSelectionMode ,其中一个值来自LoadBalancing::RegionSelectionMode ,默认值为RegionSelectionMode::DEFAULT 请明确地传递RegionSelectionMode::SELECT 的参数。

3.在通过调用Client::connect()触发的连接流程中,客户端从名称服务器接收可用区域的列表。 Listener声明一个可选的回调Listener::onAvailableRegions() 如果您已经为regionSelectionModei传递了RegionSelectionMode::SELECT ,那么Client将不会自动选择该可用区域列表中的一个项目,而是将列表传递给该回调。 因此在您的Listener实现中,您应该使用有意义的实现来覆盖该回调的空默认实现,根据您可以提出的任何条件选择一个区域。

4.连接流程完全停止,直到选择了一个区域。

5.将所选区域传递给Client::selectRegion()以继续连接流程。

注意:只有在收到对Listener::onAvailableRegions()调用之后, selectRegion()调用selectRegion()Listener::onAvailableRegions() (直接从此回调期间或之后的回调selectRegion()返回后直接调用selectRegion() )。 否则,客户端不会处于连接流程的正确阶段,进行区域选择。

Listener::onAvailableRegions()的示例实现可以在Client SDK中的demo_loadBalancing的源代码中找到:

void NetworkLogic::onAvailableRegions(const ExitGames::Common::JVector<ExitGames::Common::JString>& availableRegions, const ExitGames::Common::JVector<ExitGames::Common::JString>& availableRegionServers)
{
    EGLOG(ExitGames::Common::DebugLevel::INFO, L"%ls / %ls", availableRegions.toString().cstr(), availableRegionServers.toString().cstr());
    mpOutputListener->writeLine(L"onAvailableRegions: " + availableRegions.toString() + L" / " + availableRegionServers.toString());
    // select first region from list
    mpOutputListener->writeLine(L"selecting region: " + availableRegions[0]);
    mLoadBalancingClient.selectRegion(availableRegions[0]);
}

请注意,在接收到onAvailableRegions()的调用后, selectRegion()仅在连接流期间被调用。 在任何其他时间或状态下调用它,或者多次调用它来单次调用onAvailableRegions()并且不产生未定义的行为。

Objective-C客户端SDK

1.确保您连接到Photon Cloud。 Photon Server不支持云区域

2. EGLoadBalancingClient类的EGLoadBalancingClient有两个可选参数。 最后一个,称为regionSelectionMode ,其中一个值来自EGRegionSelectionMode.h ,默认为EGRegionSelectionMode_DEFAULT 请明确地传递该参数的EGRegionSelectionMode_SELECT

3.在您通过调用EGLoadBalancingClient::connect()触发的连接流程中,客户端从名称服务器接收可用区域的列表。EGLoadBalancingListener声明一个可选的回调EGLoadBalancingListener::onAvailableRegions() 如果您已经通过了EGRegionSelectionMode_SELECTregionSelectionMode ,那么EGLoadBalancingClient将不会自动选择该可用区域列表中的一个项目,而是将列表传递给该回调。 因此在您的EGLoadBalancingListener实现中,您应该使用有意义的实现来覆盖该回调的空默认实现,根据您可以提出的任何条件选择一个区域。

4.连接流程完全停止,直到选择了一个区域。

5.将所选区域传递给EGLoadBalancingClient::selectRegion()以继续连接流。

注意: EGLoadBalancingClient::selectRegion()只有在您收到EGLoadBalancingListener::onAvailableRegions() (直接从此回调之后调用selectRegion()之后(在回调已返回)之后selectRegion()调用。 否则,客户端不会处于连接流程的正确阶段,供区域选择。

EGLoadBalancingListener::onAvailableRegions()的示例实现可以在Client SDK中的demo_loadBalancing_objc的源代码中找到:

- (void) onAvailableRegions:(EGArray*)availableRegions :(EGArray*)availableRegionServers
{
    NSString* r = [availableRegions componentsJoinedByString:@", "];
    NSString* s = [availableRegionServers componentsJoinedByString:@", "];
    EGLOG(EGDbgLvl::INFO, L"onAvailableRegions: %ls / %ls", [r UTF32String], [s UTF32String]);
    [mOutputListener writeLine:@"onAvailableRegions: %@ / %@", r, s];
    // select first region from list
    [mOutputListener writeLine:@"selecting region: %@", availableRegions[0]];
    [mLoadBalancingClient selectRegion:availableRegions[0]];
}

请注意,在接收到onAvailableRegions()的调用后, selectRegion()仅在连接流期间被调用。 在任何其他时间或状态下调用它,或者多次调用它来单次调用onAvailableRegions()并且不产生未定义的行为。

使用中国大陆地区

首先,您需要请求访问中国大陆地区的Photon应用程序。 向我们发送表单,以便我们可以为您的AppID解锁。

光子名称服务器必须在中国本地,否则访问延迟可能会非常高。 中国光子的名称服务地址是“ns.photonengine.cn”。

与中国大陆以外的客户联系很可能不会取得好成绩。 此外,从Photon服务器连接到中国大陆以外的服务器(例如,用于自定义认证,WebHooks,WebRPC)可能不可靠。

重要提示 :在当前阶段,您通过信息中心对您的应用进行的更改不会自动反映在中国的应用高速缓存中。 如果您有更新请求,请通过电子邮件通知我们。

同样出于法律原因,您需要为中国独立构建独立的Appid,所以我们建议您使用单独的AppId。 例如,使用编译条件(您选择的)根据构建来更改AppId和Photon NameServer。

请注意,如果您连接中国区,请按照以下说明为中国区做出专门设置:

C#客户端SDK

1.将AppId设置为中国区域解锁的应用程序。 如果你想使用相同的项目并且有不同的构建,你可以这样做:

// TODO: replace compile condition with your own
#if CHINA
    loadBalancingClient.AppID = "ChinaRealtimeAppId"; // TODO: replace with your own AppId
#else
    loadBalancingClient.AppID = "nonChinaRealtimeAppId"; // TODO: replace with your own AppId
#endif

2.打开“LoadBalancingClient.cs”文件,并将NameServerHost设置为“ns.photonengine.cn”:

// TODO: replace compile condition with your own
#if CHINA
    public const string NameServerHost = "ns.photonengine.cn";
#else
    public const string NameServerHost = "ns.exitgames.com";
#endif

3.使用LoadBalancingClient.ConnectToRegionMaster(“CN”)连接中国大陆地区。

// TODO: replace compile condition with your own
#if CHINA
    loadBalancingClient.ConnectToRegionMaster("cn");
#else
    // TODO: connect to any other region
#endif

C ++客户端SDK

  • 将参数serverAdress “ns.photonengine.cn”传递给Client::connect()
  • 请确保将参数serverType保留在其默认值ServerType::NAME_SERVER

Objective-C客户端SDK

  • 将参数serverAdress “ns.photonengine.cn”传递给EGLoadBalancingClient::connect()
  • 请确保将参数serverType保持在默认值EGServerType_NAME_SERVER

关于PhotonCloud光子云的区域问题

在您默认开始使用PhotonCloud光子云的时候,区域会被默认为海外区域,这可能会严重影响您游戏的连接速度和网络品质。在您通过中国区邮件申请发送到您的账号名,联络方式和appid给我们之后,1-2个工作日内,我们将为您免费开通中国区的PhotonCloud光子云服务(初始限定为20CCU)。

快速开始


在这篇文章中,您将掌握迅速部署PhotonCloud光子云,并着手于我们的Demo“粒子演示”。 我们的SDK附带的演示向您展示了如何在一般的应用环境中如何添加多人功能。 我们将看看基本的Photon操作,并且有什么您马上安装就能使用的便捷功能。

虽然下面的C#代码示例是有点专门针对于Photon Unity3D SDK( 下载 )的,但是下面的基本工作流程(1) 连接 ,(2) 创建房间和(3) 发送事件在各平台的应用之间是通用的。

核心内容

  • 1)连接到主服务器
  • 2)创建房间/加入房间
  • 3)发送活动

连接到主服务器

您需要做的第一件事是将您的客户端连接到云端(光子云)。 我们将此过程称为连接到主服务器。 从那里,主服务器将负责所有客户端到游戏服务器的传输,云中的负载平衡功能负责协调所有可用的房间。

让我们直接进入我们的演示代码:

// From GameLogic.cs                        
public GameLogic(string masterAddress, string appId, string gameVersion) : base(masterAddress, appId, gameVersion)
{
    this.LocalPlayer.Name = "usr" + SupportClass.ThreadSafeRandom.Next() % 99;
 
    this.AutoJoinLobby = false;
    this.UseInterestGroups = true;
    this.JoinRandomGame = true;
 
    this.DispatchInterval = new TimeKeeper(10);
    this.SendInterval = new TimeKeeper(100);
    this.MoveInterval = new TimeKeeper(500);
    this.UpdateOthersInterval = new TimeKeeper(this.MoveInterval.Interval);
}

GameLogic类继承了LoadBalancingClient ,它保持一个状态并自动执行主服务器和游戏服务器之间的转换。 让我们仔细看看GameLogic构造函数中使用的参数:

  1. string masterAddress :要连接的(主)服务器的URL。 请参阅Photon云区域列表
  2. string appId :在我们的云系统中标识您的应用程序。 如果您还没有AppId,您可以在Photon Cloud信息中心 创建。 您需要插入有效的AppId才能使大多数演示工作。
  3. string gameVersion :一个字符串,你可以选择曲隔你的游戏的不同版本。 只有具有相同版本号的客户端可以匹配,并且可以相互通信。 这使得添加功能更容易,不会破坏旧客户端。

 

粒子演示截图(Unity3D SDK)

连接后,Photon云已准备好遵照你的吩咐。 你不必去做所有细微的调整,因为一切都已经为你处理好了! 在下面的图表中,您可以看到,灰色方块中的所有内容都是由Photon Cloud组织的。 客户端只需要发送简单的操作,如箭头旁边的那些。

光子云简单的工作流

现在我们连接到主服务器,我们可以列出,创建和加入房间。 在这一点上,玩家不能相互通信或交互。 这是房间的概念发挥作用。 仔细想一想,看看你需要做什么来连接玩家彼此。

大厅,创建房间和加入房间

默认情况下,当你连接时,LoadBalancing API会让你进入游戏的“Lobby”。 在大厅中,主服务器向客户端提供房间列表。 为了保持例如移动环境中的低流量,客户端不能在大厅中互相交互。

一个房间可以被认为是一个单独的区域,玩家互动(玩他们的游戏)。 当他们在同一个房间,玩家可以发送和接收来自其他人的事件,更改/更新房间的属性等。

在下面的示例中,我们使用“OpCreateRoom”操作来创建和打开房间。 一起创建一个:

RoomOptions options = new RoomOptions();
options.options.maxPlayers = 4;
peer.OpCreateRoom("Room 42", options, TypedLobby.Default);

最需要留意的参数和RoomOptions是:

  • string roomName房间的名称,用于标识和加入房间。
  • bool.RoomOptionsisVisible此变量确定房间是否在可在大厅可见的房间列表中(即连接到主服务器但还没注册但还没有进入房间中的玩家可见)。 重要的是,这些房间仍然可以加入,只要客户端知道房间的确切名称。
  • bool RoomOptions.isOpen确定客户端是否可以加入房间。 当此变量改变时,已经在房间中的客户端不受影响。 然而,他们不能在离开后重新加入房间,只要isOpenFalse的。
  • byte RoomOptions.maxPlayers决定此房间中的最大玩家数。 如果设置为0,则上限是无限的。 请注意,如果你计划在一个房间里放入大量的用户,你应该看看我们的Photon服务器MMO应用程序!
  • Hashtable RoomOptions.customRoomProperties是一组可选的键和值,您可以定义它们来描述房间。 一个可选的示例是:key“level”,值为“de_dust”。(^_^)。 属性将同步到房间中的所有客户端,并在配对中发挥作用。 更多关于这个选项,见下面。
  • string [] RoomOptions.customRoomPropertiesForLobby将在Lobby中显示的属性。

使用Photon,您可以在运行时更改房间或玩家的属性,因此通过customGameProperties设置属性,在设计服务器逻辑时你将不会有任何限制 。 在房间中使用room.SetCustomProperties(props)设置新值或覆盖现有值。 所做的更改将被合并,因此您只需要传入您想要更改的属性即可。

一个房间可以有许多属性,但通常只有几个是玩家配对所需要的,所以Photon会希望你在大厅里面定义一个房间的属性关键列表。 即使在RoomOptions.customRoomProperties中尚未定义的键也可以在string [] customRoomPropertiesForLobby中使用,并在稍后填充。

LoadBalancing房间属性示例

就像是房间的属性一样,您可以为每个玩家设置自定义属性。 每个客户端可以设置玩家属性LoadBalancingClient.localPlayer.SetCustomProperties() ,即使在加入房间之前。 他们一直保留客户端,并与客户端加入或创建的任何房间时保持同步。

LoadBalancing玩家属性示例

现在我们成功创建了一个房间,是让其他客户加入的时候了! 加入房间是非常快速和容易的,不需要任何进一步的解释,看看下面的操作:

// From LoadBalancingClient.cs                        
public void OnOperationResponse(OperationResponse operationResponse)
{
    ...
    this.OpJoinRoom(name);
}

 

接下来让我们看看玩家现在可以如何互动。

发送事件

对于客户端彼此交互,我们使用一个简单的事件系统。 使用事件是向给指定房间内的玩家发送和接收快速可靠信息的主要方式。 所有你游戏逻辑中的重要活动都可以通过这种方式进行传递。您的游戏逻辑的所有必要的数据可以在客户端之间发送。 您甚至可以通过使用简单的参数指定协议(UDP与TCP或可靠的(UDPreliable UDP)与不可靠的UDP(unreliable UDP))来自定义交换信息的方式,具体取决于您的需要。

LoadBalancing RaiseEvent操作图

活动将在房间的参与者之间分发。 您可以决定是否要将活动发送到特定的玩家团体个人的列表

让我们来看看我们在粒子演示中使用的事件,例如在更改颜色时:

public void ChangeLocalPlayercolor()
{
    if (this.LocalPlayer != null)
    {
        this.LocalPlayer.RandomizeColor();
        this.loadBalancingPeer.OpRaiseEvent(DemoConstants.EvColor, this.LocalPlayer.WriteEvColor(), this.SendReliable, new RaiseEventOptions() { CachingOption = EventCaching.AddToRoomCache });
    }
}

OpRaiseEvent参数包括:

  • byte eventCode事件代码指定要提出的实际事件。 有从由255开始向下计算的Photon的预定义事件。而从1开始到199,你可以定义在游戏逻辑中使用自己的事件。
  • Hashtable evData您可以填写此哈希表来传输您需要的所有数据。 这是您将用于在客户端之间交换信息的中央数据结构。 但是,您游戏逻辑的标准的循环和标准化步骤应该作为事件发送(例如回合结束)。
  • bool sendReliable当将此标志设置为“true”时,将从UDP切换到可靠的UDP(reliable UDP)。 这意味着在传输期间丢失的任何包将被重新发送,并且客户端将确保包将按照它们被发送的顺序被解释。 这可能会以负面的方式影响性能,因为这些额外的步骤将增加额外的消息量并增加整体通讯的数据负担。
  • byte RaiseEventOptions.channelId您可以使用不同的通道对发送的事件进行分组和优先级排序。 我们将在一个小例子中说明此功能:假设您使用渠道1发送有关玩家位置的相关信息。 你在你的游戏中启用了可靠的UDP,因为你需要在你的游戏类型获得额外的可靠性。在某些时候,通道1会由于许多消息而拥挤,因为一些玩家有延迟,因为网络连接不好而产生了一定数量的通讯包丢失,因此必须重新发送许多消息。 而这时需要入列发送另一个重要事件(如本轮结束),可能需要一些时间才能确认,因为客户端仍然忙于接收来自通道1的所有位置更新。因此,如果您现在分派一个事件到channelId 0,它将优先于所有其他排队的消息处理。 通过合理的使用此功能,您可以获得设计预期的反应性,并确保游戏逻辑的正确执行,即使在一个平庸的的连接条件下。
  • int [] RaiseEventOptions.targetActors要发送事件的房间中的ActorNumbers的列表。
  • EventCaching RaiseEventOptions.CachingOption影响服务器如何处理事件缓存。 可以缓存玩家稍后加入的事件或删除以前缓存的事件。
粒子演示(Unity3d SDK):房间视图截图

最后但并非最终的方法,Photon还有额外的重载(Overload),你可以用来指定接收器组。

想进一步了解PhotonCloud光子云?

我们推荐您学习Exit Games的官方实例教学马可波罗,您可以在光子实践资源找到被翻译为中文的教程实践连接。

请留意,如果您有自己的服务器(VPS,阿里云等),那么PhotonServer光子服务器同样可以担负PhotonCloud光子云的服务器连接功能,请参照这篇文章和光子服务器的详细介绍

error: 转摘请联络我们~