AnyEvent で echo サーバ作ってみた

最近ちょくちょく勉強している、AnyEvent で簡単な echo サーバを作ってみた。

入力された文字を単純に返すだけだと面白くないので、入力した時の日時を表示するようにしてみた。

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use DateTime;
use AnyEvent;
use AnyEvent::Socket;

my $HOST = '127.0.0.1';
my $PORT = '18888';

tcp_server $HOST, $PORT, sub {
    my ($fh, $host, $port) = @_;
    say "connected $host:$port";

    &add($fh);
};

AnyEvent->condvar->recv;

sub add {
    my $fh = shift;
    my $watcher;
    $watcher = AnyEvent->io(
        fh   => $fh,
        poll => 'r',
        cb   => sub {
            my $length = sysread $fh, my $buf, 256;
            if (! $length) {
                undef $watcher;
                return;
            }
            my $dt = DateTime->now(time_zone => 'Asia/Tokyo');
            syswrite $fh,
                '[' . $dt->ymd('/') . ' ' . $dt->hms . "] $buf";
        }
    );
}


echo サーバを起動する。

% perl ae-echo-server.pl


echo サーバに接続して、利用してみる。

% telnet 127.0.0.1 18888
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
amari3
[2010/04/05 00:35:53] amari3
AnyEvent
[2010/04/05 00:35:58] AnyEvent
hoge
[2010/04/05 00:36:01] hoge
foo
[2010/04/05 00:36:04] foo
baz
[2010/04/05 00:36:05] baz
echo server
[2010/04/05 00:36:15] echo server
^]

簡単な echo サーバだったらこんなに短いソースコードで実現できてしまう。もっと勉強してなんか面白いものを作ってみたいですね。