前回のエントリー、AS3SXはPaaSとして成功するかの続き。
AS3版PaaSとも言えるAS3SXですが、サーバ側のシステム構成は少し変わっていることを前回述べました。今回はそのシステムと通信するクライアント側に焦点を当ててみます。
AS3SXのコンセプトを台無しにする方法
前回のエントリーで少しだけ書いたのですが、AS3SXはソケットサーバをフロントに置き、クライアントはそのサーバに直接接続してTCPで通信を行っています(エンドポイントをHTTPに見せてるのは実はフェイク)。
AS3SXはその名前が示すように「クライアントもサーバもAS3で!」というのをコンセプトにサービス提供していますが、普通のTCP通信を行っているなら別に言語に縛られる必要はありません。さらに、実際に送信しているデータはクエリストリング形式の単純なASCIIデータなのでプロトコル解析の必要すらなく、自分の好きな言語で簡単にクライアントが書けます。
好きな言語といってもAS3SXのユーザーが好きな言語は当然ActionScriptだと思います。ただ、Flash Playerを必要としない環境で動作するクライアントが書けると自由にいろいろできるようになります。
例えば Shutdown Time の60分制限を回避する
AS3SXはアプリケーション毎の設定で「Shutdown Time」というものが設けられており、そこで設定した時間(最大60分)の間に新規リクエストがない場合、サーバ側のFlash Playerがシャットダウンされます。60分で勝手に落ちるものを”サーバ”とは到底呼べないので、定期的にハートビートを送ってサーバ側のFlash Playerを落ちないようにしてあげます。
簡単なハートビート送信用クライアントモジュールの実装例を載せます。本当はPHPで書いた方が良かったのかもしれませんが、Perlの方が書き慣れているので。。
* クライアント (client.pl, perl 5.8以降で動作確認)
1 2 3 4 5 6 7 8 9 10 |
#!/bin/env perl use strict; use warnings; use AS3SX::Client; ## AS3SX::Client#new の引数は「AS3SX Admin Center」で取得したID my $client = AS3SX::Client->new('your application_id here'); ## 600秒(10分)ごとにハートビート送信 $client->heartbeat(60*10); |
* AS3SX::Client モジュール (AS3SX/Client.pm, 標準モジュールのみ利用)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#!/bin/env perl package AS3SX::Client; use strict; use warnings; use Carp; use IO::Socket; ## コンストラクタ # "ClientAS3SX.setEndPoint" に相当 sub new { my ($class, $appid) = @_; my $socket = IO::Socket::INET->new( PeerAddr => "as3sx.fdt.powerflasher.com", PeerPort => 4603, Proto => 'tcp', Timeout => 5, ) or croak "connect failed: $!"; my $uuid = `uuidgen`; # UUID(GUID)を生成 chomp $uuid; my @packed = ( pack("H*", '0103000000010000006518000000'), $appid, pack("H*", '24000000'), $uuid, ); my $data = ''; $data .= $_ for @packed; $socket->send($data); bless { socket => $socket, }, $class; } sub close { $_[0]->{socket}->close; } ## ハートビート送信 (フォアグラウンドで動作) # "ClientAS3SX.sendRequest(true)" に相当 # サーバ側にはBoolean型のリクエストハンドラをハートビート受信用に書いておく sub heartbeat { my ($self, $interval) = @_; my $query = "DataService?data=BwAAAEJvb2xlYW4D&type=Boolean"; local $SIG{INT} = sub { $self->close; exit(0); }; while(1) { $self->request($query); sleep($interval); } } ## データ送信 sub request { my ($self, $query) = @_; my $magic = '010200000001000000722e000000'; $self->{socket}->send(pack("H*", $magic).$query); } 1; |
* コマンドラインから実行
1 2 3 4 5 6 |
$ ls -F AS3SX/ client.pl $ chmod +x client.pl $ ./client.pl (CTRL+Cで止める) |
データパケット内のGUIDに該当する部分を0(0x30)とハイフン(0x2d)で埋めて5秒間隔で送り、サーバ側で session.userId
をログに書き出した結果を載せます。ちゃんと足跡が付きました。
(ログのtextareaが等幅フォントになってなくて見にくい、、)
このスクリプトはフォアグラウンドで動くので SIGINT(CTRL+C) で止める必要がありますが、実際はモジュールの heartbeat
内にあるループを取り除いてcronで定期的にキックするか、デーモンにしてバックグラウンドで走らせればいいと思います。
PaaSのようなサービスを開発するに際し、最初はインビテーションで限られたユーザーだけに使ってもらい、フィードバックを経て少しずつ改善していくのが普通だと思います。でもAS3SXはアルファ版と言いつつ誰でも使える状態でいきなり公開しました。さらに、検証中に向こうのサーバに適当なパケットを送ってみたところ、なんかのオンラインゲーム上で使っていると思われるレベルとか経験値などのユーザーデータが返ってきたので、AS3SXだけではなく複数のサービスでサーバを共用しているのでしょう。
“プラットフォーム”を提供するという意識が低いのではと思いました。やはり餅は餅屋ということでしょうか。