Frequently Asked Questions
哪一種 Photon 產品適合我?
The answer to this depends mostly on your project 這個問題的答案主要取決於您的專案和團隊。
一般來說,我們建議使用Fusion或Quantum,這是我們最先進的客戶解決方案。
為了快速概覽,兩個產品表都包含產品選擇器 "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 的步驟:
- 設定新的 Windows Server EC2 執行個體
- 建立 Amazon Web Services 帳戶。
- 登入 AWS 入口網站。
- 前往「服務 -> EC2」。
- 按一下「建立實例」部分下的「啟動實例」。
- 點選對應的「選擇」按鈕,選擇 Photon Server 支援的 Microsoft Windows Server 版本。
- “選擇實例類型”,然後跳到“6. 配置安全性群組”
- 建立一個新安全性群組“Photon Server”以允許傳入端口,如 本頁.
- 按一下“審核並啟動”,然後按一下“審核”和“啟動”。
- 建立或選擇現有金鑰對。
- 勾選確認開關並點選「啟動實例」。
- 按一下「檢視實例」並等待實例完成初始化。
- RDP 連線到新執行個體
- 選擇 EC2 執行個體。
- 按一下「連線」。
- 點選「取得密碼」。
- 上傳私鑰或複製其內容,然後「解密密碼」。
- 透過點擊「下載遠端桌面檔案」來取得 RDP 捷徑。
- 透過雙擊快捷方式連接到遠端電腦。
- 輸入您的憑證並登入
- 安裝 Photon Server SDK
- 註冊Photon帳號。
- 下載 Photon 伺服器 SDK。
- 解壓縮包並將檔案複製到遠端電腦。
- 啟動Photon control。
- 將 Photon 安裝為服務。
- 啟動Photon服務。
Plugins SDK 和 Server SDK 有什麼區別?
這兩個套件提供相同的二進位檔案(“deploy”資料夾)和庫(“lib”資料夾),但原始程式碼專案(“src-server”)不同。
Photon Server SDK 可用於自託管 Photon Server 並開發 Photon Server 應用程式。裡面的原始碼是伺服器應用程式的範例。
Photon Plugins SDK 可用於自架 Photon Server 並開發自訂 Photon Server 外掛程式。裡面的原始碼是插件範例。
Threading
單一 Photon 伺服器上運行有多少個執行緒?
執行緒的使用分為:
- Native - 9 執行緒
- Managed - 基於 .Net ThreadPool 它使用.NET 預設設定
此設定已經過非常深入的測試,並且適用於各種負載設定檔。
託管線程的使用(由 .NET Windows 性能計數器報告)各不相同:
a) 在典型的 Photon 雲實時負載上約為~12
b) 35(及更多)作為運行具有插件間插件的客戶雲的示例通信(鎖定),導致一些更高的爭用(與我們的程式碼相反)
注意:如有必要, .Net ThreadPool 設定可以調整。
到目前為止,我們已經使用預設值獲得了良好的結果,儘管每個版本的預設值可能有所不同。
如何避免競爭條件和其他多線程問題?
在 Photon 中,我們盡可能地簡化了事情:
- 您可以從任何執行緒使用 PhotonPeer 方法。
- 來自 PhotonPeer 的所有通知都在一根纖程中執行(請閱讀下面有關纖程的資訊)。
- 一個房間內的所有任務都在一根纖程中執行。
- 對等點向房間的光纖發送訊息,以保護資料免受多執行緒問題的影響。
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