This document is about: SERVER 4
SWITCH TO

Frequently Asked Questions

哪一種 Photon 產品適合我?

The answer to this depends mostly on your project 這個問題的答案主要取決於您的專案和團隊。
一般來說,我們建議使用FusionQuantum,這是我們最先進的客戶解決方案。

為了快速概覽,兩個產品表都包含產品選擇器 "Quadrant":

如有任何問題,請隨時與我們聯絡。

Load Balancing

Photon 房間支援的最大玩家數量是多少?

大多數 Photon 多人遊戲有 2-16 名玩家,但每個房間的玩家/同伴的理論限制可能相當高。
有些 Photon 遊戲有 32 名甚至 64 名玩家,在虛擬會議場景中可能有數百名玩家。
但是,每秒發送太多訊息(每個房間的訊息/秒)可能會導致效能問題,這取決於客戶端處理資料的處理能力。
雖然回合製遊戲等玩家數量較多完全沒問題,但快節奏動作遊戲中超過 32 名玩家可能會要求您實施興趣管理。
這樣一來,並非每個玩家都會收到來自所有其他玩家的每個訊息。

每個房間的玩家數量是增加遊戲房間內數據流量的主要因素:這就是為什麼我們建議將每個房間

訊息數/秒數保持在 500 以下。。
密切注意您的頻寬使用情況始終很重要,它有助於確保您保持在計劃中包含的每個 CCU 3GB 的流量範圍內。

光子串有限制嗎?

Photon

將字串用於多種用途:房間名稱、大廳名稱、使用者 ID、暱稱、自訂屬性鍵等。
強烈建議使用最短的字串字串可能。

對於名稱和使用者 ID,36 個字元就足夠了(例如 GUID 是 36 個字元)。
對於自訂屬性鍵,您應該使用較短的字串以最大限度地減少其開銷。
這對於大廳中可見的屬性尤其重要,因為這些屬性是房間清單的一部分,並將發送給大廳中的每個人,而不僅僅是房間中的幾個客戶。

自訂屬性的數量有限制嗎?

是的,有一個限制:每個使用者可以設定 13k 個鍵值,而且房間中的總大小不能超過 500kB。
設定的自訂屬性越多,客戶端加入房間所需的時間就越長,因為客戶端會收到所有屬性。

我可以使用 Photon 發送大訊息嗎?

我們不建議使用 Photon 傳輸大數據(即檔案),除非您知道自己在做什麼。
我們建議您優化交換的數據,如果您確實需要發送非常重要的訊息,請與我們聯絡。

Photon Cloud 對客戶端緩衝區的伺服器端限制為 500KB。

因此,根據上下文,可以考慮一則訊息:

  • 對於 Photon Cloud 上的每個客戶端緩衝區大小「太大」> 500KB。如果客戶端在短時間內達到此限制,伺服器將斷開連線。
  • “太大”,無法使用 UDP 發送,而不會產生可能導致問題的碎片量 > 100KB。
  • “太大”,如果不將其分割成多個 > 1.2KB 的 UDP 封包(包括協定開銷),則無法傳送。

對於經常發送的訊息(每秒 10 次或更頻繁),我們建議將其大小保持在 1KB 以下。

如果訊息很少發送(例如在比賽開始時發送一次),那麼多個 KB 的大小仍然可以,但我們仍然建議將其保持在 10KB 以下。

較大的訊息可以在單獨的 Enet 通道(UDP 中)中傳送,這對其他通道(狀態同步)的影響較小。

對於大文件,請考慮使用單獨的後端。

哪些資料應該可靠地發送,哪些資料應該不可靠地發送?

首先,您應該知道只有當使用的協定是 UDP 時,可靠性才是一個選項。
TCP 有自己的「可靠性」機制,此處未介紹。

發送可靠的內容意味著 Photon 確保它到達目標客戶端。
因此,如果客戶端沒有及時收到確認,他們將重複發送,直到收到確認或超過重發次數。
此外,重複可靠的事件可能會導致額外的延遲並使後續事件延遲。

不使用可靠性的範例:

  • 即時遊戲中的玩家位置更新
  • 語音或視訊聊天(串流)

使用可靠性的範例:

  • 回合製遊戲中的回合事件
  • 很少變化的分數更新

為什麼我這樣做我的遊戲有這麼多斷線嗎?

斷開連接可能是由於各種原因造成的。
我們已經有這個文件頁面可以幫助您調查相關問題:「[Analyzing Disconnects](~/realtime/current/troubleshooting/analyzing-disconnects]」。

每個房間每秒的訊息數是如何計算的?

Photon 伺服器每秒計算入站和出站訊息總數,並將其除以房間總數(在同一主伺服器上)。

任何操作請求或操作回應或事件都被視為訊息。
光子操作會傳回可選的操作回應並觸發零個或多個事件。
快取的事件也算作訊息。

每次室內操作的訊息費用:

Operation Success: Best Case Success: Average Case Success: Worst Case
Create 2
(SuppressRoomEvents=true)
3
+ Join event (SuppressRoomEvents=false, default)
3
Join 2 + k
(SuppressRoomEvents=true)
+ k * cached custom event
2 + n + k
+ n * Join event (SuppressRoomEvents=false, default)
2 + 2 * n + k
+ n * ErroInfo event (HasErrorInfo=true)
Leave 2
(SuppressRoomEvents=true)
1 + n
+ (n - 1) * Leave event (SuppressRoomEvents=false, default)
2 + (n - 1) * 2
+ (n - 1) * ErroInfo event (HasErrorInfo=true)
RaiseEvent 1
(no operation response)
(target: interest group with no subscribers)
1 + n
+ n * custom event
(target: all/broadcast)
2 + 2 * n
+ n * ErroInfo event (HasErrorInfo=true)
+ Auth event (token refresh)
SetProperties 2
Broadcast=false
2 + n
+ n * PropertiesChanged event (default: Broadcast=true, BroadcastPropertiesChangeToAll=true)
2 + 2 * n
+ n * ErrorInfo event (HasErrorInfo=true)
+ 1 in case of CAS or BroadcastPropsChangeToAll

如何計算使用者消耗的流量?

這是一個複雜的話題。
首先您需要知道所做的任何計算都只是理論估計,可能不會反映現實。
我們建議建立概念驗證並使用它來收集真實數據。

這裡所說的是如何估計房間內單一使用者產生的流量:

讓我們假設以下內容:

  • 一個房間有 N 個玩家。
  • 玩家每秒發送 F 訊息(訊息發送速率以 Hz 為單位)
  • 平均訊息大小為 X(以位元組為單位,負載 (P) + 協定開銷 (O))
  • 玩家平均每月在遊戲上花費H 小時

如果我們不考慮 ACK、連線處理(建立、保持活動等)命令和重新發送。
然後我們說,平均而言,一個 CCU 在您的遊戲中消耗 C(以位元組/月為單位),如下所示

C = X * F * N * H * 60 (每小時分鐘) * 60 (每分鐘秒)

斷線後如何快速重新加入房間?

若要從加入房間時意外斷開連線中恢復,用戶端可以嘗試重新連線並重新加入房間。
我們稱之為「快速重新加入」。
只有在滿足以下條件時,快速重新加入才會成功:

  • 房間仍然存在於同一伺服器上或可以加載:
    如果玩家離開房間,如果其他玩家仍然加入,則後者可以在 Photon 伺服器上保持活動狀態。
    如果玩家是最後一個離開的並且房間變空,則 EmptyRoomTTL 是等待玩家加入或重新加入時保持活動狀態的時間。
    如果在 EmptyRoomTTL 之後房間仍然是空的並且沒有人加入,那麼它將從 Photon 伺服器中刪除。
    如果滿足持久性條件並且設定了 Webhooks,則可以將房間狀態保存在配置的 Web 服務上以便稍後載入。
  • 演員在內部被標記為非活動狀態:具有相同 UserId 的演員存在於演員列表中,但目前未加入房間。
    這要求 PlayerTTL 不同於 0

    只要房間還活著,如果在停用時間後經過了 PlayerTTL 毫秒,相應的演員就會從演員名單中刪除。
    否則,當演員嘗試重新加入時,如果重新加入嘗試時間與停用時間之間的毫秒差超過 PlayerTTL,則演員將從演員列表中刪除,並且重新加入失敗。
    因此,非活動參與者只能在停用時間後的 PlayerTTL 毫秒內重新加入房間。

「快速重新加入」由兩個步驟組成:

  • 重新連接:一旦斷開連接,只需呼叫適當的連接方法即可。
  • 重新加入:呼叫loadBalancingClient.OpRejoin(roomName)

On-Premises

在上面的範例中,客戶端的 cmd_rtt 在 62ms 到 124ms 之間;在 11 秒內沒有收到最後一個命令的 ACK 後,它被斷開。

不可以。
Photon Server 只限用於 Windows 。
請閱覽 "Requirements" 以了解更多詳細內容。

如何在Amazon託管 Photon Server?

在 Amazon 上託管 Photon Server 的步驟:

  1. 設定新的 Windows Server EC2 執行個體
  • 建立 Amazon Web Services 帳戶。
  • 登入 AWS 入口網站。
  • 前往「服務 -> EC2」。
  • 按一下「建立實例」部分下的「啟動實例」。
  • 點選對應的「選擇」按鈕,選擇 Photon Server 支援的 Microsoft Windows Server 版本。
  • “選擇實例類型”,然後跳到“6. 配置安全性群組”
  • 建立一個安全性群組“Photon Server”以允許傳入端口,如 本頁.
  • 按一下“審核並啟動”,然後按一下“審核”和“啟動”。
  • 建立或選擇現有金鑰對。
  • 勾選確認開關並點選「啟動實例」。
  • 按一下「檢視實例」並等待實例完成初始化。
  1. RDP 連線到新執行個體
  • 選擇 EC2 執行個體。
  • 按一下「連線」。
  • 點選「取得密碼」。
  • 上傳私鑰或複製其內容,然後「解密密碼」。
  • 透過點擊「下載遠端桌面檔案」來取得 RDP 捷徑。
  • 透過雙擊快捷方式連接到遠端電腦。
  • 輸入您的憑證並登入
  1. 安裝 Photon Server SDK
  • 註冊Photon帳號。
  • 下載 Photon 伺服器 SDK。
  • 解壓縮包並將檔案複製到遠端電腦。
  • 啟動Photon control。
  • 將 Photon 安裝為服務。
  • 啟動Photon服務。
  1. 從 Windows 防火牆開啟所需連接埠

Plugins SDK 和 Server SDK 有什麼區別?

這兩個套件提供相同的二進位檔案(“deploy”資料夾)和庫(“lib”資料夾),但原始程式碼專案(“src-server”)不同。
Photon Server SDK 可用於自託管 Photon Server 並開發 Photon Server 應用程式。裡面的原始碼是伺服器應用程式的範例。
Photon Plugins SDK 可用於自架 Photon Server 並開發自訂 Photon Server 外掛程式。裡面的原始碼是插件範例。

Threading

單一 Photon 伺服器上運行有多少個執行緒?

執行緒的使用分為:

  1. Native - 9 執行緒
  2. Managed - 基於 .Net ThreadPool 它使用.NET 預設設定

此設定已經過非常深入的測試,並且適用於各種負載設定檔。

託管線程的使用(由 .NET Windows 性能計數器報告)各不相同:

a) 在典型的 Photon 雲實時負載上約為~12
b) 35(及更多)作為運行具有插件間插件的客戶雲的示例通信(鎖定),導致一些更高的爭用(與我們的程式碼相反)

注意:如有必要, .Net ThreadPool 設定可以調整。
到目前為止,我們已經使用預設值獲得了良好的結果,儘管每個版本的預設值可能有所不同。

如何避免競爭條件和其他多線程問題?

在 Photon 中,我們盡可能地簡化了事情:

  1. 您可以從任何執行緒使用 PhotonPeer 方法。
  2. 來自 PhotonPeer 的所有通知都在一根纖程中執行(請閱讀下面有關纖程的資訊)。
  3. 一個房間內的所有任務都在一根纖程中執行。
  4. 對等點向房間的光纖發送訊息,以保護資料免受多執行緒問題的影響。

Fiber纖程是一個任務列表,這些任務以 FIFO 方式依序執行。
這並不意味著它們在一個線程中執行。
實際上,它們是在許多線程中執行的,但是是一個一個執行的。
因此第一個任務可能在執行緒 A 中執行,當它完成時,第二個任務可能在執行緒 B 中執行,依此類推。
但在每一給定時刻只有一個執行緒存取房間資料。
當許多纖程存取相同資料時,我們使用鎖。
例如,在房間的快取中。

您可以如下使用光纖:

C#

// rooms contructor
someFiber = new PoolFiber(); // create new fiber
someFiber.Start();
someFiber.ScheduleForInterval(someRepetitiveRoutine, 0, 100); // start immediately and repeat every 100 ms, ie 10 times per second. this params may vary as you need
// at some other point, where you need to add more logic to the fiber
someFiber.Enqueue(newTask);
someFiber.Enqueue(()=>{ anotherTask(parameters);});
// from the tasks you can send messages to the room e.g. to notify the room of a result of a task
room.EnqueueMessage(new YourCustomMessage(somethingToSend));

請記住,如果您使用共享相同代碼或相同資料的多個自訂纖程,那麼您需要同步訪問,因為不同纖程中的操作是同時執行的。

Logging

如何在每次用戶端連線或中斷連線時寫入日誌條目?

將其加入應用程式的 log4net.config 中:

XML


<logger name="Photon.SocketServer.ApplicationBase">
    <level value="DEBUG"/>
</logger>

Output from "{MyApplication}.log":

Successful connect:

2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - ConnID=17, IP 127.0.0.1 on port 4530
2013-05-02 11:19:02,506 [23] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnInit - response sent to ConnId 17 with SendResult Ok

Disconnect:

2013-05-02 11:19:07,608 [24] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnDisconnect - ConnID=17

當 Photon 向客戶端發送操作回應時如何寫入日誌條目?

將其新增至應用程式的「log4net.config」:

XML


<logger name="Photon.SocketServer.PeerBase">
    <level value="DEBUG"/>
</logger>

Output from "{MyApplication}.log":

2013-05-02 11:19:02,569 [21] DEBUG Photon.SocketServer.PeerBase [(null)] - SentOpResponse: ConnID=17, opCode=255, return=0, ChannelId=0 result=Ok size=14 bytes

當 Photon 收到客戶端的操作請求時,如何寫入日誌條目?

這種日誌記錄最好在應用程式的 Peer 類別(繼承自“HivePeer”)中完成。

XML


<logger name="Photon.Hive.HivePeer">
    <level value="DEBUG"/>
</logger>

Output from "{MyApplication}.log":

2013-05-02 11:19:02,553 [21] DEBUG Photon.Hive.HivePeer [(null)] - OnOperationRequest. Code=255

您可以在OnOperationRequest方法中修改日誌條目的內容。

C#

protected override void OnOperationRequest(OperationRequest operationRequest, SendParameters sendParameters)
{
    if (log.IsDebugEnabled)
    {
        log.DebugFormat("OnOperationRequest. Code={0}", operationRequest.OperationCode);
    }
    // snip
}

為什麼我的客戶端會斷開連線?如何調試超時?

若要了解用戶端斷開連線的原因,請將應用程式設定為在對等方呼叫「OnDisconnect」時寫入偵錯日誌條目。

XML


<logger name="Photon.Hive.HivePeer">
    <level value="DEBUG"/>
</logger>

在您的 Peer 類別(繼承自 HivePeer)中,您的 OnDisconnect() 方法應如下所示:

C#

protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail)
{
    if (log.IsDebugEnabled)
    {
        log.DebugFormat("OnDisconnect: conId={0}, reason={1}, reasonDetail={2}", this.ConnectionId, reasonCode, reasonDetail);
    }
    //     
}

Output from "{MyApplication}.log":

2013-05-02 11:19:07,639 [12] DEBUG Photon.Hive.HivePeer [(null)] - OnDisconnect: conId=17, reason=ClientDisconnect, reasonDetail=

如果您使用 UDP:在「TimeoutDisconnect」的情況下,「reasonDetail」將包含 RoundTripTime 歷史記錄,如下所示:

index - sequence - rtt - variance - sentTime - recvTime - cmd_rtt

0 - 326 - 0 - 0 - 830717056 - 830728351 - 11295
1 - 325 - 89 - 19 - 830715918 - 830716042 - 124
2 - 324 - 85 - 14 - 830714826 - 830714904 - 78
3 - 323 - 86 - 17 - 830712751 - 830712813 - 62
4 - 322 - 89 - 14 - 830711659 - 830711737 - 78
5 - 321 - 90 - 16 - 830710551 - 830710645 - 94
6 - 320 - 90 - 19 - 830709428 - 830709537 - 109
7 - 319 - 88 - 19 - 830708320 - 830708414 - 94
8 - 318 - 88 - 23 - 830707197 - 830707306 - 109
9 - 317 - 86 - 24 - 830706105 - 830706183 - 78
10 - 316 - 87 - 29 - 830704701 - 830704763 - 62
... etc ...

每行包含以下值:

  • Index 索引 (0...49,其中0是最新的,49是最旧的。仅显示最后50个条目。)
  • Sequence序列 - 一个递增的序列号
  • rtt (往返时间 - 当前的RTT,单位为毫秒 - 在处理ACK或发生超时时可用)
  • variance 方差 (当前方差,单位为毫秒)
  • sentTime 发送时间 (命令被发送的时间)
  • recvTime 接收时间 (ACK被接收的时间)
  • cmd_rtt (命令发送和ACK接收之间的时间跨度,单位为毫秒)

在上面的範例中,客戶端的 cmd_rtt 在 62ms 到 124ms 之間;在 11 秒內沒有收到最後一個命令的 ACK 後,它被斷開。

計費

您是否為學生、業餘愛好者或獨立開發者提供特別優惠?

我們所有的產品都有免費套餐和一次性入門方案。
我們通常也會參加Unity的資源商店銷售活動,偶爾也會贈送代金券給幸運兒。

我可以為單一 Photon 應用程式組合多個 100 CCU 方案嗎?

不可以。

每個AppId只能申請一個。
它們可以與付費訂閱相結合,並在有效期內使用。

如果您的單一應用程式需要更多 CCU,下一個更高的方案是 500 CCU 方案。
如果您訂閱月度或年度方案,那麼除了月度/年度方案中的 CCU 之外,您仍將保留 100 個 CCU 12 個月。

我的 Photon 計畫包含多少流量?

Photon Cloud 和 Premium Cloud 方案包括每個 CCU 3GB。

例如, 1,000 個 CCU 的月度方案每月包含 3 TB 的流量。

如果您的應用程式產生超用流量,我們將自動透過電子郵件發送提醒。您將在月底透過您的 Photon 帳戶電子郵件收到超額使用通知。該內容金額基於以下計算:

總流量 - 包含流量 = 超額流量(以 GB 為單位)

流量以每 GB 2.38台幣/4.75台幣計算,具體取決於所使用的 Photon Cloud 區域。該費用會追加到下個月費用清單裡。

如果峰值 CCU 超過我的 Photon Cloud 方案預訂的 CCU,會發生什麼情況?

如果您訂閱了 500 CCU / 1,000 CCU / 2,000 CCU 方案,則會自動為您的應用程式啟動「CCU Burst」。 Photon Cloud 將允許比您預訂的更多的 CCU,以便為您的用戶提供最佳體驗。

但是一旦Burst啟動,您有義務根據商定的條款在 48 小時內升級到所需的訂閱等級。

如果您不升級,我們將向您的 Photon 帳戶電子郵件發送“超額通知”,並收取超出您訂閱方案的每個 CCU 按 32.4台幣/33台幣/43.2台幣(基於所使用的 SDK)的費用。該費用會自動追加到您的下個月費用清單裡。

Photon 以「峰值 CCU」收費,即給定月份內每個區域的峰值 CCU 的總和。即使達到高峰後使用量減少,也請務必升級,以免產生超額費用。

Back to top