FelicaToNetからのデータを受信するためのベースクラスです。
まだ、PODドキュメントもほとんど書かれていませんし、配布ファイルにもまとめられておらず、ソースがあるだけです。 分かる人だけが使ってください。
Perlのライブラリ検索パス内に、適切に配置してください。
配置が正しくできていれば、以下のコマンドラインで、受信を開始することができます。 起動後に、FelicaToNetで接続、読み取り、切断などをやってみてください。
perl -MNet::FelicaFromNet -e "Net::FelicaFromNet->new->start;"
ライブラリとしては、オブジェクトを生成し、startを呼ぶことで上記と同様の受信開始ができます。 startを呼ぶ前に、callbackメソッドにサブルーチンのリファレンスを渡しておくと、FelicaToNetからのデータ受信時に、そのコールバックルーチンが呼ばれます。 コールバックサブルーチンに渡される引数は、Net::FelicaFromNet?オブジェクト、IO::Socketオブジェクト、以下のキーを持つハッシュデータです。
| キー | 内容 |
| event | 発生したイベントを表わす、"NEW CLIENT"、"NEW MESSAGE"、"END CLIENT"のいずれかの文字列 |
| address | データの受信下を現すIPアドレス(文字列) |
| client | FelicaToNetで設定したクライアントID |
| felica | FelicaToNetで読み取ったカードID(カードを外した時は"0") |
| time | 読み取りを行った時刻 |
コールバックサブルーチンの内容は、ソース内にある、デフォルトで使用されるdefault_callbackサブルーチンを参考にしてください。
package Net::FelicaFromNet;
use strict;
use base qw(Class::Accessor);
use vars qw($VERSION);
use IO::Socket;
use IO::Select;
$VERSION = '0.01';
Net::FelicaFromNet->mk_accessors(qw(port listener selecter callback));
sub new {
my $class = shift;
my $port = (@_) ? shift : 4321;
my $self = bless {}, $class;
$self->port($port);
return $self;
}
sub start {
my $self = shift;
my $port = $self->port;
# lsitenerの取得
my $listener = $self->listener;
if (not $self->listener and $port) {
$listener = IO::Socket::INET->new(
LocalPort => $port,
Listen => SOMAXCONN,
Proto => 'tcp',
Reuse => 1,
);
die "listen できませんでした。 $!\n" unless ( $listener );
$self->listener($listener);
}
# listen
my $callback = $self->callback || \&default_callback;
my $selecter = IO::Select->new;
$selecter->add($listener);
$self->selecter($selecter);
while ($self->selecter) {
my ($active_socks) = IO::Select->select($self->selecter,undef,undef,undef);
foreach my $sock (@{$active_socks}){
if ($sock == $self->listener){
my $new_sock = $sock->accept;
my $new_addr = $new_sock->peerhost;
&{$callback}($self, $new_sock, {'event' => "NEW CLIENT", 'address' => $new_addr});
$selecter->add($new_sock) if ($new_sock);
} else {
my $addr = $sock->peerhost;
my $buf = <$sock>;
if ( $buf ){
chomp($buf);
my ($client, $felica, $time) = split(/,/, $buf);
&{$callback}($self, $sock, {'event' => "NEW MESSAGE", 'address' => $addr, 'client' => $client, 'felica' => $felica, 'time' => $time});
$sock->flush() if ($sock);
} else {
&{$callback}($self, $sock, {'event' => "END CLIENT", 'address' => $addr});
$selecter->remove($sock);
$sock->close() if ($sock);
}
}
}
}
return $self->listener;
}
sub default_callback {
my $self = shift;
my $sock = shift;
my $event = shift;
if ($event->{'event'} =~ /^(NEW|END) CLIENT$/) {
printf("[%s] %s\n", $event->{'event'}, $event->{'address'});
} elsif ($event->{'event'} eq 'NEW MESSAGE') {
printf("[%s] %s:%s %s at %s\n", (map { $event->{$_} } qw(event address client felica time)));
} else {
eval '
use Data::Dumper;
local $Data::Dumper::Indent = 0;
local $Data::Dumper::Sortkeys = 1;
';
printf("[%s]\n%s\n", 'UNKOWN', Dumper($event));
}
}
1;
__END__
=head1 NAME
Net::FelicaFromNet - Receiver base module for FelicaToNet
=head1 SYNOPSIS
perl -MNet::FelicaFromNet -e "Net::FelicaFromNet->new->start;"
=head1 SEE ALSO
L<http://www.mobiquitous.com/pub/sd200501-2.html#5>
=head1 COPYRIGHT
Copyright 2006-2006 Makio Tsukamoto <tsukamoto@gmail.com>
This library is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=cut