sleep (あるいは LWP::UserAgent などのそのほかのブロックする処理) をすると、たとえコールバック内でも nonblocking では処理されない。
$http_request_cb で sleep しているこの例は blocking で、 sleep を消せば nonblocking になる。ブロックさせたくない場合は timer を使う。
#!/usr/bin/perl use strict; use warnings; use utf8; use Encode; use AnyEvent; use AnyEvent::HTTP; use AnyEvent::Socket; use AnyEvent::Handle; use Data::Dumper; use XML::Simple; my $server = get_alertinfo(); my $http_request_cb; $http_request_cb = sub { my ($body, $hdr) =@_; my $xml = XMLin(decode_utf8 $body); print Dumper $xml->{request_id}; sleep 5; }; my $socket_read_cb; $socket_read_cb = sub { my ($handle, $chat_tag) = @_; $chat_tag = XMLin(decode_utf8 $chat_tag); if (defined $chat_tag->{content}) { my ($lv_num, $co_num, $user_id) = split/,/, $chat_tag->{content}; if (defined $lv_num && defined $co_num && defined $user_id) { print Dumper $lv_num; my $url = 'http://live.nicovideo.jp/api/getstreaminfo/lv'; http_request( GET => "$url$lv_num", timeout => 3, $http_request_cb ); } } $handle->push_read(line => "\0", $socket_read_cb); }; my $connection_cb; $connection_cb = sub { my ($fh) = @_ or die $!; my $thread_tag_attr = { thread => $server->{thread}, res_from => '-1', version => '20061206', }; my $thread_tag = XMLout($thread_tag_attr, RootName => 'thread') . "\0"; my $handle; $handle = new AnyEvent::Handle( fh => $fh, on_error => sub { warn "Error $_[2]\n"; $_[0]->destroy; }, on_eof => sub { $handle->destroy; warn "Done\n"; } ); $handle->push_write($thread_tag); $handle->push_read(line => "\0", $socket_read_cb); }; my $cv = AE::cv; my $connection = tcp_connect( $server->{addr}, $server->{port}, $connection_cb, ); $cv->recv; sub get_alertinfo { my $url = 'http://live.nicovideo.jp/api/getalertinfo'; use LWP::UserAgent; my $ua = LWP::UserAgent->new(); my $res = $ua->get($url); die $res->status_line unless $res->is_success; my $xml = XMLin($res->decoded_content); die "Fatal: Server status $xml->{status}" if $xml->{status} ne 'ok'; return $xml->{ms}; }