バイナリプロトコル
Photonとそのクライアントは、非常に最適化されたバイナリプロトコルを使用して通信します。
このバイナリプロトコルは、コンパクトで容易に解析できるのが特長です。 バックエンドで処理されるため詳細を知る必要はありませんが、ここでは念のため詳述します。
通信レイヤー
Photonのバイナリ―プロトコルはいくつかのレイヤーで構成されています。 最下層のレベルでは、送信したいメッセージの転送にUDPが使用されます。
これらの標準のデータグラム内で、一部のヘッダーはPhotonで使用するプロパティを反映しています:
オプションの信頼性、シーケンシング、メッセージの集約、時間の同期やその他のプロパティです。
下図では、個々のレイヤーとそのネスト化を示します。
すべてのUDPパッケージにはeNetヘッダーと、少なくとも1つのeNetコマンドが含まれます。
各eNetコマンドはメッセージを転送します:オペレーション、結果、またはイベントなどです。
これらのメッセージはオペレーションヘッダーと、提供されたデータで構成されています。
下表にはプロトコルの各部とそれらのサイズが記載されています。 この表から、コンテンツを送信する際に必要なトラフィックを概算できます。
必要に応じて、任意のメッセージのサイズがどれくらい大きくなるかについても算出できます。
以下に例を示します。
例:「somegame」に参加
(ライトアプリケーションまたはLoadBalancingアプリケーションによって実装される) JoinRoom
オペレーションを見てみましょう。
プロパティがない場合、これは1つのパラメータを持つオペレーションです。
「オペレーションパラメータ」には以下が必要です:2 + count(パラメーターキー) + size(パラメーター値) バイト。
文字列「somegame」はUTF8エンコーディングで8バイト使用し、文字列にはさらに3バイト必要です(長さとタイプの情報)。合計:14バイト。
パラメータは8バイトのオペレーションヘッダーにラップされています。
合計:22バイト。
オペレーションコードは、パラメータとしてエンコードされません。 その代わりに、オペレーションコードはオペレーションヘッダー内にあります。
オペレーションとそのヘッダーはeNetの「高信頼性を送信」コマンドにペイロードとしてラップされます。
コマンドは12バイトです。合計:34バイト。
他のコマンドがキューされていない場合に、コマンドが送信されたとします。
eNetパッケージヘッダーは12バイトです。高信頼性のシーケンスされたオペレーションの場合は合計:46バイトです。
最後にeNetパッケージはUDP/IPデータグラムに投入され、28バイトのヘッダーが追加されます。
これまでの46バイトと比べて、かなり少ないです。 残念ながらこれを完全に回避することはできないのですが、
コマンドの集約化によってこれらのヘッダーが共有され、トラフィックが大幅に節減されます。
オペレーション全体では、合計74バイトになります。
サーバーはこのコマンドを確認する必要があります。ACKコマンドは20バイトです。
パッケージ内で単独で送信された場合には、40バイトを占めます。
Enetチャネル
Enetチャネルを使用すると、複数の独立したコマンドシーケンスを使用できます。 1つのチャネルでは、すべてのコマンドは順番に送信され、ディスパッチされます。
高信頼性コマンドが不足している場合、受信側はアップデートの送信を続行できなくなり、ラグが発生します。
一部のイベント(およびオペレーション)が他から独立している場合、個別のチャネルに入れることができます。 例:ルーム内のチャットメッセージは高信頼性であるべきですが、遅れて受信される場合には(一時的に)不足しているメッセージによって位置のアップデートが遅延されるべきではありません。
デフォルトではPhotonには2つのチャネルがあり、チャネル0がオペレーションを送信するためのデフォルトです。 オペレーションjoinとleaveは(簡易化ため)チャネル0で送信されます。 メッセージの接続と切断には、内部的に使用される「バックグラウンド」チャネル255があります。 このチャネルはチャネルカウントには含まれません。
チャネルには優先順位があります:まず最も低いチャネル番号が置かれます。 UDPパッケージが既にいっぱいの場合、より高いチャネル内のデータが後に送信される可能性があります。
オペレーションコンテンツ ー シリアル化が可能な型
シリアル化が可能なPhotonの型と、それぞれのサイズについての詳細は こちらのリンクから表を参照してください。
クライアント側では、オペレーションパラメータとそれらの値はハッシュテーブル内に集約されます。 各パラメータはバイトキーに似ていますが、オペレーションリクエストは合理化され「通常」のハッシュテーブルよりも少ないバイトが使用されます。 オペレーションの結果とイベントは、オペレーションパラメータと同じ方法でエンコードされます。 オペレーション結果には常に「オペレーションコード」、「リターンコード」、「デバッグ文字列」が含まれます。 イベントには常に「イベントコード」と「イベントデータ」ハッシュテーブルが含まれます。
Enetコマンド
名前 | サイズ | 送信元 | 説明 |
---|---|---|---|
connect |
44 |
クライアント |
高信頼、接続ごと |
verify connect |
44 |
サーバー |
高信頼、接続ごと |
init message |
57 |
クライアント |
高信頼、接続ごと(アプリケーションを選択) |
init response |
19 |
サーバー |
高信頼、initごと |
ping |
12 |
両方 |
高信頼、間隔をおいて呼び出し(他に高信頼のものがない場合) |
fetch timestamp |
12 |
クライアント |
ただちにレスポンスされるping |
ack |
20 |
oth 両方 |
低信頼、高信頼性コマンドごと |
disconnect |
12 |
両方 |
高信頼、タイムアウトの場合に低信頼の可能性あり |
send reliable |
12 + ペイロード |
両方 |
高信頼、オペレーション、レスポンスまたはイベントを送信 |
send unreliable |
16 + ペイロード |
両方 |
低信頼、オペレーション、レスポンスまたはイベントを送信 |
fragment |
32 + ペイロード |
両方 |
高信頼、ペイロードが1つのデータグラムにおさまらない場合に使用 |
UDPパケットコンテンツ - ヘッダー
名前 | サイズ[バイト] | 説明 |
---|---|---|
udp/ip |
28 + サイズ(オプションのヘッダー) |
IP + UDPヘッダー オプションのヘッダーは40バイト以下 |
enet packet header |
12 |
byte.MaxValueコマンドまでを含む (上記参照) |
operation header |
8 |
コマンド内(reliable, unreliable or fragment 高信頼、低信頼またはフラグメント) オペレーションパラメータを含む (上記参照) |