FxUG in Toyama # Presented by wacky
最近 AMF 3 の Encode/Decode を実装してみました。 そこで得た知識を共有したいと思います! 30分後には … AMF の基本構造が分かっている AMF の得手不得手が分かっている BlazeDS の弱点も分かっている
Action Message Format の略、データ形式の一種。 仕様は Adobe から公開されている。 ActionScript 3(Flex2 以降 ) の型に対応している。 Flash Player 9 から使用可能。 AMF 3 仕様 :
Marker (string) Marker (string) ABC (UTF-8) x 3バイト x 3バイト xxxxxxx1 参照ではない xxxxxxx1 参照ではない
Marker (array) Marker (array) x 2要素 x 2要素 xxxxxxx1 参照ではない xxxxxxx1 参照ではない Marker (string) Marker (string) xxxxxxx0 参照 xxxxxxx0 参照 x 0番目 x 0番目 空文字列 ( 疎データ無 )
AMF 3 では、3種類の参照情報を管理している。 文字列 オブジェクト (Object, Array, Date, XML, ByteArray) Traits 情報(オブジェクトの型情報) プロパティー名リストのようなもの 既出の文字列は、 2~5 バイトで送信可能。 既出のオブジェクトも、 2~5 バイトで送信可能。 ただし、同一インスタンスの場合のみ 既出の Traits 情報も、 2~5 バイトで送信可能。
整数 (int) は可変バイトで Encode される。 ※ Size は Marker に必要な 1 byte を含む。 ※ int 領域全体での平均サイズは、実は約 8.5 byte … ※ Vector 内の int は固定バイト ( 4 byte) となる。
整数 (long) は固定で Marker + 8 バイトに Encode ただし、形式は double 形式。 つまり、桁落ちします … long の範囲 ( 64 bit) ~ 正しく Encode → Decode できる範囲 ( 53 bit) ~ ※元々、 Flex 上では表現できない数字だけど …
サンプルデータ(異なる値) // Sample: Dynamic 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push({ index: k, message: "Message" + k }); } // Sample: Sealed 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push(new Bean(k, "Message" + k)); } // Sample: Dynamic 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push({ index: k, message: "Message" + k }); } // Sample: Sealed 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push(new Bean(k, "Message" + k)); }
サンプルデータ(同じ値、別インスタンス) // Sample: Dynamic 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push({ index: 999, message: "Message999" }); } // Sample: Sealed 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push(new Bean(999, "Message999")); } // Sample: Dynamic 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push({ index: 999, message: "Message999" }); } // Sample: Sealed 値 var target:Array = []; for (var k:int = 0; k < 1000; k++) { target.push(new Bean(999, "Message999")); }
サンプルデータ(同一インスタンス) // Sample: Dynamic 値 var target:Array = []; var item:Object = { index: 999, message: "Message999" }; for (var k:int = 0; k < 1000; k++) { target.push(item); } // Sample: Sealed 値 var target:Array = []; var item:Bean = new Bean(999, "Message999"); for (var k:int = 0; k < 1000; k++) { target.push(item); } // Sample: Dynamic 値 var target:Array = []; var item:Object = { index: 999, message: "Message999" }; for (var k:int = 0; k < 1000; k++) { target.push(item); } // Sample: Sealed 値 var target:Array = []; var item:Bean = new Bean(999, "Message999"); for (var k:int = 0; k < 1000; k++) { target.push(item); }
同一データを重複送信しないだけ。圧縮すると減る。
実は、 AMF 3 の仕様書に載っていない 新しいデータタイプが存在 … Flash Player 10 を使用すると発生 …
Java 5 対応されていない Enum: 文字列にエンコード。デコードは未対応。 Generics: 無視される。※ List とか厳しい … Unicode のサロゲートペア未対応 Encode: サロゲートペア1文字が、 6 バイト (UTF-8) に Encode されてしまう。※正しくは4バイト Decode: Flash Player 10 で Encode したサロゲートペアを Decode すると例外が発生。 Flash Player 10 未対応 Vector を扱えない。 Dictionary を扱えない。 ※ BlazeDS で確認