Unibaの暑中見舞いARについて

弊社よりお送りしました暑中見舞いの参考動画です。
ご覧頂いた方も頂いていない方も是非Uniba.jpよりご覧ください。

記事はこちらよりどうぞ

Hoppy を使ってみる

自分、このブログ作らせた言い出しっぺなのに記事全然書けてませんね。
文章書くの好きだけども、苦手だからか。
ずっと書かないのもなんなので、仕事で触れたネタは極力書くようにします。

今、Flash を使ってリアルタイム Web するお仕事をしてます。Flash は余り詳しくないのですが、XMLSocket という機能を使って サーバと通信する事で、それを実現出来るらしいですね。

結構昔からある技術らしくてサーバとしてのソリューションはそれなりの数が出ているらしいけれども、何がいいかはよくわからない、というところで Hoppy を使ってみる事にしました。選んだ理由は、Perl で書かれていたから。とは言え、いわゆるモダン Perl という奴も実は余り詳しくなかったりします。Perl の知識は10年以上前に CGI とか書いてた頃のままなので。とはいえ、Java とかで書かれてる他のソリューションよりは扱い易いかな、という気がしたんです。Java も不案内なので。そうするとお前何が出来るんだよ、とかいう話になりそうですが、そんな事考えると眠くなるので、弄ってみる事にします。

で、使おうと決めたらまずは資料探しなのですが、残念な事に余りヒットしない。

このくらい?

仕方ないので体当たりで使ってみる事にしました。しかし、恐しい事に「POEって何?」というところから始まる手探り感です。まずは Hoppy.pm を眺めてみます。

Hoppy クラスを new した時に _setup メソッドが呼ばれて POE の本体部分が初期化されるのだな。


POE::Component::Server::TCP->new(
	Alias => $self->config->{alias} || 'xmlsocketd',
	Port  => $self->config->{port}  || 10000,
	ClientConnected    => sub { $self->_tcp_handle( Connected    => @_ ) },
	ClientInput        => sub { $self->_tcp_handle( Input        => @_ ) },
	ClientDisconnected => sub { $self->_tcp_handle( Disconnected => @_ ) },
	ClientError        => sub { $self->_tcp_handle( Error        => @_ ) },

	ClientFilter => $filter,
	InlineStates => {
		Send => sub {
			$self->_tcp_handle( Send => @_ );
		},
	},
);
POE::Kernel->sig( INT => sub { POE::Kernel->stop } );

その前に、_load_classes メソッドで諸々の、部品として使われそうな各クラスを読み込んでいる。これは、プラガブルにするための工夫だよね。

で、そうして作った POE を start メソッドで走らせ始める、とそういう流れらしい。その程度のホントに漠然とした理解ですけど、実際に使ってみようと書いたコードが以下

test.pl

#!/usr/bin/perl

BEGIN {
	unshift(@INC, '.');
}

use Hoppy;
use Data::Dumper;

my $config = {
	alias => 'hoppy',
	port => 12345,
	test => 2,
};

my $server = Hoppy->new(config => $config );

$server->regist_service(
	broadcast => 'MyService::Broadcast',
	unicast => 'MyService::Unicast',
	multicast => 'MyService::Multicast',
);

$server->regist_hook(
	client_input => 'MyHook::ClientInput',
);

$server->start;

基本的には、作者様のスライドで示されたサンプルの猿真似。

最初に @INC を弄っているのは、同一パスにある Hoppy を CPAN で入れた物より優先ささせるため。その下で読み込んでる Data::Dumper と組み合わせて、本体のあちこちに中身どうなってるのか変数をダンプしてまわる行を足してみたかったのでこういう事をしてます。

Hoppy.pm 内には、broadcast, multicast, unicast の3つのメソッドがあったのでそれらを全て試してみることに。また、Hook の仕組みも試してみたかったので、クライアントからの入力をフックして処理を走らせるようにもしてみました。

MyService/Broadcast.pm

package MyService::Broadcast;

use base qw(Hoppy::Service::Base);
use Data::Dumper;

sub work {
	my $self = shift;
	my $args = shift;
	my $c = $self->context;
	my $in_data = $args->{in_data};
	my $poe = $args->{poe};
	my $session_id = $poe->session->ID;

	print "now broadcastting\n";

	$c->broadcast({
			sender => $session_id,
			message => $in_data->{params}->{message},
		});

	print "broadcasting done\n";
}

1;

MyService/Multicast.pm

package MyService::Multicast;

use base qw(Hoppy::Service::Base);
use Data::Dumper;

sub work {
	my $self = shift;
	my $args = shift;
	my $c = $self->context;
	my $in_data = $args->{in_data};
	my $poe = $args->{poe};
	my $session_id = $poe->session->ID;
	my $user_id = $in_data->{params}->{user_id};

	print "now multicastting\n";

	$c->multicast({
			sender => $session_id,
			room_id => $c->{room}->{where_in}->{$user_id},
			message => $in_data->{params}->{message},
		});

	print "multicasting done\n";
}

1;

MyService/Unicast.pm

package MyService::Unicast;

use base qw(Hoppy::Service::Base);
use Data::Dumper;

sub work {
	my $self = shift;
	my $args = shift;
	my $c = $self->context;
	my $in_data = $args->{in_data};
	my $poe = $args->{poe};
	my $session_id = $poe->session->ID;
	my $user_id = $in_data->{params}->{user_id};

	print "now unicastting\n";

	$c->unicast({
			sender => $session_id,
			user_id => $in_data->{params}->{target_id},
			message => $in_data->{params}->{message},
		});

	print "unicasting done\n";
}

1;

MyHook/ClientInput.pm

package MyHook::ClientInput;

use Data::Dumper;
use base qw(Hoppy::Hook::Base);

sub work {
	my $self = shift;
	my $args = shift;
	my $c = $self->context;

	print Dumper($c);
}

1;

これで、チャットサーバ的な物が出来ました。

test.pl を実行しておいて、telnet から接続し、以下のような入力を順に送るとメッセージが送れたりします。(送った本人には届かないので、テストの為には二カ所以上から telnet する必要があります)

{"method":"login","params":{"user_id":"test","room_id":"testing_room"}}
{"method":"broadcast","params":{"user_id":"test","message":"broadtestes"}}
{"method":"multicast","params":{"user_id":"test","message":"multitestes"}}
{"method":"unicast","params":{"user_id":"test","target_id":"test2","message":"unitestes"}}

Perl よくわからないながらも、とりあえず動くようになったので、もう少しいじり回してみようと思います

Flash Lite の中身を動的に変更する

swfmill というツールの存在を知った。swf ファイルと XML ファイルを相互に変換するという。Flash Lite 1.1 の中身を動的に更新したいという声が社内で上がっていた(何年周回遅れで??)ので、それを試しに使ってみる事にした。

サンプルで使う Flash Lite 1.1 のファイルは以下のようなものを用意した。
手抜きだが必要充分だろう。

This movie requires Flash Player 4.0.0
QRコード
http://dev.uniba.jp/~rei/swfmill/test.swf

swfmill の利用実績は豊富にある。
まずは、Flash4 の仕様に準拠するために文字コードが UTF-8 でない Flash Lite 1.1 に対応するために下記ページで配布されているパッチを当てる必要があるらしい。

Continue reading »

Flash で グラフを書く

以前、案件で使ったライブラリについて書いておく。
Open Flash Chart 2 といって、Flash で書いたグラフをページ内に埋めこめるツール。
シンプルだけど高機能で、色んな種類のグラフが書ける。

単純なグラフはもちろん

This movie requires Flash Player 9.0.0

棒グラフ(ガラス的装飾付き)とか・・・

This movie requires Flash Player 9.0.0

円グラフ

This movie requires Flash Player 9.0.0

こういうのはローソクチャートって言うんだっけ

This movie requires Flash Player 9.0.0

公式サイトにはこの他にも     なサンプルがあるみたい。

使い方は続きで
Continue reading »

preload preload preload