AnyEventのサンプル

最近何も書いていなかったのでAnyEventの復習でお茶を濁す

AnyEvent::Introにも載っているサンプル。

普通に標準入力からの入力を待ち受けるスクリプトとどう違うの?というような疑問を持ってしまうサンプル。

use strict;
use warnings;
use AnyEvent;
use AnyEvent::Strict;

$|++;
print "Enter Your Name: ";
my $cv = AE::cv;
my $watcher;
$watcher = AnyEvent->io(
    fh   => \*STDIN,
    poll => 'r',
    cb   => sub {
        my $str = <STDIN>;
        chomp $str;
        undef $watcher;
        $cv->send($str);
    }
);
print $cv->recv, "\n";

AnyEvent->timerなどと組み合わせるとその理由がわかってくる

標準入力からの待ちうけはblockingになるがAnyEventを使ってevent loopにしておくことでtimer等で、ある一定時間入力がなければそれを解除することもできる。

use strict;
use warnings;
use AnyEvent;
use AnyEvent::Strict;

$|++;
print "Enter Your Name: ";

my $cv = AE::cv;
my ( $watcher, $timer );
$watcher = AnyEvent->io(
    fh   => \*STDIN,
    poll => 'r',
    cb   => sub {
        my $str = <STDIN>;
        chomp $str;
        undef $watcher;
        undef $timer;
        $cv->send($str);
    },
);

$timer = AnyEvent->timer(
    after => 3,
    cb    => sub {
        print "\n";
        undef $watcher;
        undef $timer;
        $cv->send("3sec passed");
    },
);
print $cv->recv, "\n";

AnyEvent::Socketで簡単にエコーサーバーもどきを作る

上記の2例を組み合わせて作った。telnetで接続し、クライアント側から3秒間何も入力がなければサーバの側から接続を切る。

use strict;
use warnings;
use AnyEvent::Socket;
use AnyEvent::Strict;

my $cv = AE::cv;
my ( $w, $t, $res );

tcp_server '127.0.0.1', 8888, sub {
    my ($fh) = @_ or die;
    syswrite $fh, AnyEvent->now . " Enter: ";
    $w = AnyEvent->io(
        fh   => $fh,
        poll => 'r',
        cb   => sub {
            sysread $fh, $res, 1024;
            undef $w;
            undef $t;
            syswrite $fh, AnyEvent->now . " -- " . $res . "\015\012";
        },
    );

    $t = AnyEvent->timer(
        after => 3,
        cb    => sub {
            undef $w;
            undef $t;
            syswrite $fh, "\015\012";
            syswrite $fh, AnyEvent->now . " -- 3sec passed\015\012";
        },
    );
};
$cv->recv;