Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-settings.php on line 472

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-settings.php on line 487

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-settings.php on line 494

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-settings.php on line 530

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-includes/cache.php on line 103

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-includes/query.php on line 21

Deprecated: Assigning the return value of new by reference is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-includes/theme.php on line 623
馬鹿全 - サーバーサイドASのAS3SXとその考察

Home > AS3SX | ActionScript3.0 > サーバーサイドASのAS3SXとその考察

サーバーサイドASのAS3SXとその考察


Deprecated: Function split() is deprecated in /virtual/jessejds/public_html/blog.bk-zen.com/wp-content/themes/wp.vicuna.ext/functions.php on line 358

node.js が盛り上がっている中「AS3 がサーバーサイドで動くよ」という記事が Twitter で流れてきた。

AS3SX Server Side Action Script 3 Library & Hosting
http://as3sx.com/

盛り上がりや、ある程度の概要はこちらを見たらいいと思う。

サーバーサイドASのAS3SXがちょっと凄そうな件についてのまとめ - Togetter
http://togetter.com/li/185777

今回はそれらの使い方などの説明ではなく、それらの仕組みに注目し考察していこうと思う。
想像を多く含むので間違いもたくさんあるかも。

詳細は以下から。

サーバーサイドのASはどうやって動いているか

この手のサービスが現れた時、最初に思ったのは Tamarin を使用しているのだろうという事だ。
http://www.mozilla-japan.org/projects/tamarin/

以前紹介した、Redtamarin はこの Tamarin を使用し、改良を加えたものだ。
その為、Tamarin の仕様上 FP9 までの AS3 しか使えない。

しかし、AS3SX は Vector などの FP10 以降の API も使用できた。

次に、Tamarin 同様、独自のバーチャルマシンを作成し、その上で SWF を動かしているのでは?と考えた。
その方法であれば、FP10 以降の API を使用できている理由も納得できた。

試しに、Capabilities.serverString をトレースしてみたところ 以下のようなスペックがわかった。

A=t&SA=t&SV=t&EV=t&MP3=t&AE=t&VE=t&ACC=f&PR=t&SP=f&SB=f&DEB=t&V=WIN%2010%2C2%2C153%2C1&M=Adobe%20Windows&R=800×600&COL=color&AR=1.0&OS=Windows%20Server%202003%20R2&ARCH=x86&L=de&IME=t&PR32=t&PR64=t&PT=StandAlone&AVD=f&LFD=f&WD=f&TLS=t&ML=5.1&DP=72

これらからわかる事は OS は Windows Server 2003 R2FlashPlayer のバージョンは 10,2,153,1 でスタンドアローンタイプ
言語はドイツ語、画面の大きさは 800×600 などなど。

という事は、VM上で動いているわけではなく、SWF はサーバー側でスタンドアローンプレイヤーで立ち上がり、その SWF とクライアントサイドの SWF とでやり取りを行っている事がわかった。

どうやって通信を行っているのか

最初 itoz さんが作ったサンプルを見た時は GET か POST で HTTP リクエストを投げると返すだけの仕組みかと思ったが
HTTP リクエストが送られている状況を見る限り、そのような情報は見られない。

どうやら Socket でサーバーと繋ぎ、通信を行っているようだ。

AMF でやり取りができるため、自分で作った Class のオブジェクトを送ることもできる。

Socket はどの段階で接続されるのか

AS3SX で行う事は非常に少ない。
リクエストを投げるにはクライアントSWFに以下の二行をかくだけでよい。

ClientAS3SX.setEndPoint(END_POINT); // END_POINT は登録時に取得できる。
ClientAS3SX.sendRequest(data);

この2行のどちらかで Socket をつなげているはず。

ドキュメントには載っていないが、SocketConnection というクラスを発見した。
SocketConnection には static な instance というプロパティがあり、それの connected でどうやら判断できそうだ。
それによると Socket は EndPoint を設定した段階で 1, 2秒後に connected が true になった。

どこに繋いでいるのか

試しに EndPoint に null を突っ込んでみた。
すると、ヌルポエラーが帰ってきた。
どうやら、設定されるはずの文字列にアクセスしようとしてエラーを吐いたようだ。
つまり、この文字列から何かを取得しようとしたという事だ。
次に空文字列を突っ込んでみる。
今度は「条件は未定義であり、プロパティがありません」とのエラー。
今度のエラーが意味するものは「空文字列に何かを施した結果にアクセスし、その結果のプロパティが未定義だったという事」
このエラーはおそらく Array で起こるエラーだ。
String.split で分割しようとしたが、予想される個数の要素が無く、
[""] という空文字列が一つだけ入った配列の 0 でない index にアクセスし、そのプロパティを参照しようとしたらしい。
本来 http://as3sx.com/Apps/[ID]/ この形で END_POINT は渡される。
これらを短くして渡してみた。
すると、http:// の段階でエラーが出なくなった。
もしかしたら / で分割して as3sx.com を取ろうとしていたのではないだろうか?という予想がついた。
http:// の後に自分のサイトの URL 等を入れれば、自分のサイトに繋ぎに来るのではないだろうかと思って試そうとしたが、
ここまで来て、エラーが起こっていたクラスの ConnectionData に host というプロパティがあり、そこが変化することに気付きそこまではやらなかった。

ConnectionData のプロパティを見る限り、やはり as3sx.com を取得していた。
この段階で本当に Socket をつないでいるのだろうか?という疑問は残るが、次に進む事にする。

さて、as3sx.com におそらく Socket が接続されたであろう事がわかったが、やってみれば気付く事がある。
最初のリクエストを投げた時、平均40~50秒ほど間が空き、そのあとサーバーサイドのレスポンスが帰ってくるという事だ。
その後のレスポンスは Socket 通信を行っているだけあって速い。
※1度レスポンスが帰ってきたら複数人で接続してみても最初のリクエストのレスポンスは速い。

そのタイムラグはなぜ生まれるのか

SWF を立ち上げるのにそんなに時間がかかるのだろうか?
そう思い、サーバーサイドに getTimer() を仕込んでみた。
getTimer() を使う事で、FlashPlayer が起動してからの時間が取得できる。
サーバーサイドのメインクラスのコンストラクタと、リクエストハンドラ内に仕込んでみる。
すると、コンストラクタとリクエストハンドラでの時間差はそれほどなく、SWF が読み込まれてから間もなくしてリクエストハンドラが呼ばれている事がわかった。

しかし、その時間を見るとやはり起動してから40秒ほど経過していた

これが何を意味しているかと言うと、サーバーサイド用の SWF はさらに別の SWF から読み込まれている事になる。

その別 SWF の正体とは

loaderInfo から URL を取得してみるとわかった。
どうやら、アップした SWF は file:///C:/WWW/AS3Server/UserSwfs/bin/[GUID].swf のように保存されているらしい。
GUID は 8,4,4,4,12 桁の 16進数で表現され、間にハイフンを含む36文字で構成されている。
例: 26fde9ed-06bc-4d0f-8773-cb399e73eb6c
この SWF のファイル名は、1プロジェクトで共通ではなくアップし直すたびに変更されるらしい。

そして最初に起動し、アップした SWF を読み込む SWF は file:///C:\WWW\AS3Socket\Container\SWFContainer.swf?GUID=[GUID] のような URL になっていた。
ここでの GUID は先ほどのアップした SWF のGUIDではなく、別の GUID だった。
構成は16進数32文字。MD5 に似ている。
※ ちなみに ?GUID=hogehoge とすることで FlashVars と同じように loaderInfo の パラメーターで取得することができる。

SWFContainer はどのタイミングで起動されるのか

今までのテストでは EndPoint を設定してすぐにリクエストを投げていた。
それを EndPoint を設定した後、20秒ほど待ってリクエストを投げてみた。
すると getTimer で取得した時間は 60秒ほどに伸びていた。
つまり、先ほどの残った疑問「EndPoint で本当に Socket を接続しているのか」という疑問が解けたという事と、SWFContainer は、Socket が繋がれたタイミングで起動されている事がわかった。
さらに、60秒ほどに伸びているという事は、
Loader で サーバーSWFが読み込まれるのは、最初のリクエストを送った時から40秒後という事になる。

ではなぜ SWFContainer が必要なのだろうか

そもそも、なぜ SWFContainer が間に噛んでいるのだろうか?という疑問もあった。
少なくとも2つの理由があるんだろうと自分は考えた。

1.サーバーサイドエラーの取得

サーバーサイドのエラーが、クライアントサイドでトレースができるのだが、それってどうやってるんだろう?
と思っていたが、おそらくこの SWFContainer が uncaughtErrorEvents を使って取得し、それをクライアントに送信している。
その時にエラーログも書いているのだろう。

2.サーバーサイド SWF のライブラリ内 Class の置換と追加

サーバーサイドでログを出力する場合は、ServerTrace.trace(”hoge”); のようにやると出力されるのだが、
ローカルでテストをすると、ローカルではトレースされるだけで出力はされない。
そのあたりや、他にもSWCに含む必要のないクラスの処理をクラスごと置換してるかもしれない。

「クラスの置換?何それ?」って人はこちらを読むといいかも。
BeInteractive! [Loader と ApplicationDomain による実行時クラス置換]
http://www.be-interactive.org/index.php?itemid=428

2008年の記事。相変わらず何歩も先を行ってる方ですw

まとめ

図のような構成になっていると想像できる。

  • クライアントSWF は Socket サーバーと通信。
  • Socket をつなげるのは EndPoint を設定した時。
  • Socket がつながると、サーバー側で SWFContainer.swf が立ち上がる。
  • その時に SWFContainer.swf がローカル(クライアントから見たらサーバー内)の Socket サーバーとつながる。
  • クライアントSWF からリクエストが送られる。
  • SWFContainer.swf が何かしらもじゃもじゃして、40秒ほど時間がかかる。
  • その後 Loader で サーバーSWF が読み込まれる。
  • サーバーSWF がリクエストを受け取る。
  • リクエストを返す。

最後に

こうやって推理し、見えない仕組みを丸裸にしていく事はとても面白い。
推理小説なんかが大好きな人はやってみるといいかも。
想像力はデバッグ力です。

何にせよ、この40秒の起動時間が何とかならない限り、サービスに使うのは難しいかもしれない・・・。

追記

サーバー側の設定で “Run in Debug Player” のチェックボックスをはずすと速くなった!

Home > AS3SX | ActionScript3.0 > サーバーサイドASのAS3SXとその考察

Search
Feeds
Meta

Return to page top