ここではメインプログラムの作り方について説明します。
BBS.pmはイベント駆動システムでイベントが発生するとイベントに連動してハンドラが呼び出されます。
呼び出されるハンドラに処理ルーチンを設定することでアプリケーションサーバを作成することができます。
BBS.pmの制約はごくわずかですので、自由なコードスタイルでメインプログラムを作成することができますが、ひな形を使うことで簡単に作成することができます。
以下はメインプログラムのひな形です。
package App;
use BBS;
my $bbs = new BBS;
sub onconnect {
my $self = shift;
$self->setapphandler( sub { $self->App::appWork(@_) } );
}
sub ondisconnect {
my $self = shift;
}
sub onrecv {
my $self = shift;
my $recvdata = shift;
}
sub onsend {
my $self = shift;
my $senddata = shift;
}
sub output {
my $self = shift;
return $senddata;
}
sub appwork {
my $self = shift;
}
$bbs->setsyshandler('onConnect', sub { $bbs->App::onconnect(@_) });
$bbs->setsyshandler('onDisconnect', sub { $bbs->App::ondisconnect(@_) });
$bbs->setsyshandler('onRecv', sub { $bbs->App::onrecv(@_) });
$bbs->setsyshandler('onSend', sub { $bbs->App::onsend(@_) });
$bbs->setsyshandler('Output', sub { $bbs->App::output(@_) });
$bbs->start(8888);
メインプログラムでは以下の4つの手順を行います。
(1) BBS.pmのロードとオブジェクトの作成
(2) 各ハンドラで実行するルーチンの定義
(3) 実行するルーチンのハンドラ設定
(4) サーバ開始
BBS.pmはメインプログラムから
use BBS;
my $bbs = new BBS;
とすることでロードされ、作成したオブジェクトに対して命令を行うことでサーバアプリケーションを操作します。
各イベントに対する処理(ルーチン)を定義します。
定義するルーチンはBBS.pmのパッケージ(BBS)から呼び出されますので、第一引数にはBBS.pmオブジェクトが渡ります。
Perlでは関数(メソッド)を定義する際、習慣的に第一引数の変数名をselfとすることがありますが、このselfにBBS.pmオブジェクトが入りますのでルーチン内でBBS.pmに対して命令を行う場合は、
$self->function()
とします。
ルーチンを定義するときの関数名について制約はありませんが、登録するハンドラ名を使用するのが適切です。
sub onconnect {
my $self = shift;
:
}
onSendハンドラでは関数send()の引数である送信データの引き渡しが行われますので第二引数の指定が必要です。
sub onsend {
my $self = shift;
my $data = shift; # 送信データ
:
}
またonRecvハンドラではonAccessイベント処理で取得した受信データの引き渡しが行われますので第二引数の指定が必要です。
sub onrecv {
my $self = shift;
my $data = shift; # 受信データ
:
}
そのほか、Outputハンドラではノードにデータを送出するための専用ハンドラです。
送出するデータをハンドラの返り値にセットしてハンドラを抜けることで、ノードにデータが送出されます。
sub output {
my $self = shift;
return $senddata; # 送信データ
}
用法や注意事項など、詳しくはハンドラのページをご覧ください。
定義したルーチンをハンドラに設定するときは関数setsyshandler()で
$bbs->setsyshandler( 'onConnect', sub { $bbs->App::onconnect() } );
のようにします。
ルーチンの設定はメインプログラム(のパッケージ上)で行いますので、作成したBBS.pmオブジェクトの変数(ここではbbs)に対して命令を行うことに注意してください。
onSend, onRecvハンドラでは通信データの引き渡しが行われますので、ルーチン内で通信データが受け取れるよう、
$bbs->setsyshandler( 'onSend', sub { $bbs->App::onsend( @_ ) } );
や
$bbs->setsyshandler( 'onRecv', sub { $bbs->App::onrecv( @_ ) } );
のように引数を渡すように指定します。
他のハンドラでは引数によるデータの受け渡しは行われませんので引数の指定を省略できますが、全てのハンドラ設定をonSend, onRecvハンドラの設定と同じようにすることで、データの引き渡しが行われないミスを防ぐことができます。
ハンドラ設定が概ね完了すれば、
$bbs->start(8888);
とすることでサーバが開始し、ノードからの着信を待機します。
ハンドラに設定するルーチンは別のパッケージで定義しておき、ハンドラ設定を行うときに別のパッケージにあるルーチンを指定すれば、メインプログラムは
use App;
use BBS;
my $bbs = new BBS;
$bbs->setsyshandler('onConnect', sub { $bbs->App::onconnect(@_) });
$bbs->setsyshandler('onDisconnect', sub { $bbs->App::ondisconnect(@_) });
$bbs->setsyshandler('onRecv', sub { $bbs->App::onrecv(@_) });
$bbs->setsyshandler('onSend', sub { $bbs->App::onsend(@_) });
$bbs->setsyshandler('Output', sub { $bbs->App::output(@_) });
$bbs->start(8888);
とするだけで完成します。
また、アプリケーションの規模が小規模で1つのファイルに収めたい場合は、前述のように全てのハンドラ処理の定義とハンドラ設定をメインプログラム上で行うことも可能です。
コードスタイルは作成するサーバアプリケーションの規模によって決めておくことで、メンテナンスなどの負担を減らすことができます。