Photonでの直列化
Photonとクライアントは、非常に最適化されたバイナリプロトコルを通信に使用しています。
このバイナリプロトコルは簡潔で、容易に解析できます。
Photonは送信前に、すべてのデータをこのバイナリプロトコルに変換する必要があります。
この処理は、通常使用されるデータ型について自動的に実行されます。
ほとんどのクライアントAPIでは、必要となる他のクラスに独自の直列化手順を登録することも可能です。
以下を参照してください。
Photonでサポートされている型
Photonでサポートされているそれぞれの型には、 type_infoに予約バイトが必要です。
- 基本タイプはtype_infoに1バイト必要です。
- 多くのコレクションは、コレクションの型に対して追加のもう1バイトを必要とします。
コレクションの型がtype_infoの一部であるHashtableやObject配列、Byte配列の場合にはその限りではありません。 - 厳密に型指定されたコレクションは要素の型を一度送信します。要素ごとにtype_infoを送信するわけではありません。
- すべてのコレクションは、長さを保管するのに2バイトを必要とします。これは長さの型が
short
であることによります。
バイト配列はこのルールの例外です。バイト配列はint
の型で、長さを保管するのに4バイト必要です。 - 文字列[]にnull値を含めることはできません。代わりに空白を使用してください。
以下の型には多くの場合対応しており、Photonのバイナリプロトコルで認識されます。
リストに載っている全ての型を備えていない言語では、SDKがサポートする型が少ない場合もあります。
Type (C#) | Size [bytes] (photon_sizeof) | Description |
---|---|---|
byte | 2 | 8 bit unsigned 2 = type_info(byte) + sizeof(byte) |
bool (boolean) | 2 | true or false 2 = type_info(bool) + sizeof(bool) |
short | 3 | 16 bit 3 = type_info(short) + sizeof(short) |
int (integer) | 5 | 32 bit 5 = type_info(int) + sizeof(int) |
long | 9 | 64 bit 9 = type_info(long) + sizeof(long) |
float | 5 | 32 bit 5 = type_info(float) + sizeof(float) |
double | 9 | 64 bit 9 = type_info(double) + sizeof(double) |
String | 3 + sizeof( UTF8.GetBytes(string_value) ) | length ≤ short.MaxValue 3 = type_info(String) + length_size; length_size = sizeof(short) |
Object[] (Object-array) | 3 + photon_sizeof(elements) | length ≤ short.MaxValue 3 = type_info(Object[]) + length_size; length_size = sizeof(short) |
byte[] (byte-array) | 5 + length | length ≤ int.MaxValue 5 = type_info(byte[]) + length_size; length_size = sizeof(int) |
array (array of type T, T[]) | 4 + photon_sizeof(elements) - length * type_info(T) | length ≤ short.MaxValue T-type can be any of the types listed in this table except byte. 4 = type_info(array) + type_info(T) + length_size; length_size = sizeof(short) |
Hashtable | 3 + photon_sizeof(keys) + photon_sizeof(values) | pairs count ≤ short.MaxValue 3 = type_info(Hashtable) + length_size; length_size = sizeof(short) |
Dictionary<Object,Object> | 5 + photon_sizeof(keys) + photon_sizeof(values) | pairs count ≤ short.MaxValue 5 = type_info(Dictionary) + 2 * type_info(Object) + length_size; length_size = sizeof(short) Dictionary keys should not be of type Dictionary. |
Dictionary<Object,V> | 5 + photon_sizeof(keys) + photon_sizeof(values) - count(keys) * type_info(V) | pairs count ≤ short.MaxValue V-type can be any of the types listed in this table. 5 = type_info(Dictionary) + type_info(Object) + type_info(V) + length_size; length_size = sizeof(short) Dictionary keys should not be of type Dictionary. |
Dictionary<K,Object> | 5 + photon_sizeof(keys) + photon_sizeof(values) - count(keys) * type_info(K) | pairs count ≤ short.MaxValue K-type can be any of the types listed in this table. 5 = type_info(Dictionary) + type_info(K) + type_info(Object) + length_size; length_size = sizeof(short) Dictionary keys should not be of type Dictionary. |
Dictionary<K,V> | 5 + photon_sizeof(keys) + photon_sizeof(values) - count(keys) * (type_info(K) + type_info(V)) | pairs count ≤ short.MaxValue K- and V-types can be any of the types listed in this table. 5 = type_info(Dictionary) + type_info(K) + type_info(V) + length_size; length_size = sizeof(short) Dictionary keys should not be of type Dictionary. |
カスタム型
通信する全てのクライアントにカスタムタイプを登録してください。
Custom Types
上記リストに含まれていない型の場合、重要な値をシリアライズ化または非シリアライズ化する必要があります。
基本的には二つのメソッドを書いてクラスをバイト配列に変換してから戻します。その後にそれをPhoton APIに登録します。
登録が完了すれば、メッセージにその型のインスタンスを含むことができます。
type_infoに2バイトをもつカスタム型:
1バイトはこれがカスタム型であることを示し、そしてもう1バイトはカスタムコード型用です。
Photonでは256のカスタム型をサポートしています。カスタム型コードの推奨数は255以下です。
Photonが登録された型のシリアライズ化メソッドを呼び、自動的に作成したバイト配列(4byte)をプリフィックスします:
2バイトは必要な型情報のため、もう2バイトはペイロード長のためです。
4バイトのオーバーヘッドがあるので、バイトの少ないデータの登録は避けた方が良いかもしれません。
Photon Serverは不明のカスタムタイプをそのまま転送することもできます。 このため、Photon Cloudではタイプの登録をする必要がありません。
通信する全てのクライアントにカスタム型を登録してください。
必要な場合にはサーバーサイドもしくはプラグインにカスタム型を登録してください。
RegisterType
メソッドは、ブーリアンの結果を返します。この結果で型が登録可能か判断します。
カスタム型の登録中に何かしらのエラーが生じた場合は、メソッドがfalse
を返し、変更は何も起こりません。
それ以外の場合、登録は正常に行われtrue
値が返されます。
カスタムコードがすでに使用されている場合は、登録は正常に行われずメソッドはfalseを返します。
同一のカスタム型に対して登録済みのシリアル化・デシリアル化メソッドの上書きは行われず、古いものが使われ続けます。
サーバ上でカスタムタイプを登録
Photon Serverのシリアル化で不明なタイプを登録するには、TryRegisterCustomTypeを使います。
C#
Protocol.TryRegisterCustomType(typeof(MyCustomType), myCustomTypeCode, MyCustomType.Serialize, MyCustomType.Deserialize);
タイプをbyte-arrayに書き込んで受信側に再生成するには二つの方式が必要です。例として、MyCustomTypeを実装しました:
C#
public class MyCustomType
{
public byte Id { get; set; }
public static object Deserialize(byte[] data)
{
var result = new MyCustomType();
result.Id = data[0];
return result;
}
public static byte[] Serialize(object customType)
{
var c = (MyCustomType)customType;
return new byte[] { c.Id };
}
}