AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Intro.pod view on Meta::CPAN
your process was sent a signal (such as C<SIGTERM> or C<SIGUSR1>).
Child-process watchers wait for a child process to exit. They are useful
when you fork a separate process and need to know when it exits, but you
do not want to wait for that by blocking.
Idle watchers invoke their callback when the event loop has handled all
outstanding events, polled for new events and didn't find any, i.e., when
your process is otherwise idle. They are useful if you want to do some
non-trivial data processing that can be done when your program doesn't
have anything better to do.
All these watcher types are described in detail in the main L<AnyEvent>
manual page.
Sometimes you also need to know what the current time is: C<<
AnyEvent->now >> returns the time the event toolkit uses to schedule
relative timers, and is usually what you want. It is often cached (which
means it can be a bit outdated). In that case, you can use the more costly
C<< AnyEvent->time >> method which will ask your operating system for the
current time, which is slower, but also more up to date.
=head1 Network programming and AnyEvent
So far you have seen how to register event watchers and handle events.
This is a great foundation to write network clients and servers, and might
be all that your module (or program) ever requires, but writing your own
I/O buffering again and again becomes tedious, not to mention that it
attracts errors.
While the core L<AnyEvent> module is still small and self-contained,
the distribution comes with some very useful utility modules such as
L<AnyEvent::Handle>, L<AnyEvent::DNS> and L<AnyEvent::Socket>. These can
make your life as a non-blocking network programmer a lot easier.
Here is a quick overview of these three modules:
=head2 L<AnyEvent::DNS>
This module allows fully asynchronous DNS resolution. It is used mainly by
L<AnyEvent::Socket> to resolve hostnames and service ports for you, but is
a great way to do other DNS resolution tasks, such as reverse lookups of
IP addresses for log files.
=head2 L<AnyEvent::Handle>
This module handles non-blocking IO on (socket-, pipe- etc.) file handles
in an event based manner. It provides a wrapper object around your file
handle that provides queueing and buffering of incoming and outgoing data
for you.
It also implements the most common data formats, such as text lines, or
fixed and variable-width data blocks.
=head2 L<AnyEvent::Socket>
This module provides you with functions that handle socket creation
and IP address magic. The two main functions are C<tcp_connect> and
C<tcp_server>. The former will connect a (streaming) socket to an internet
host for you and the later will make a server socket for you, to accept
connections.
This module also comes with transparent IPv6 support, this means: If you
write your programs with this module, you will be IPv6 ready without doing
anything special.
It also works around a lot of portability quirks (especially on the
windows platform), which makes it even easier to write your programs in a
portable way (did you know that windows uses different error codes for all
socket functions and that Perl does not know about these? That "Unknown
error 10022" (which is C<WSAEINVAL>) can mean that our C<connect> call was
successful? That unsuccessful TCP connects might never be reported back
to your program? That C<WSAEINPROGRESS> means your C<connect> call was
ignored instead of being in progress? AnyEvent::Socket works around all of
these Windows/Perl bugs for you).
=head2 Implementing a parallel finger client with non-blocking connects
and AnyEvent::Socket
The finger protocol is one of the simplest protocols in use on the
internet. Or in use in the past, as almost nobody uses it anymore.
It works by connecting to the finger port on another host, writing a
single line with a user name and then reading the finger response, as
specified by that user. OK, RFC 1288 specifies a vastly more complex
protocol, but it basically boils down to this:
# telnet freebsd.org finger
Trying 8.8.178.135...
Connected to freebsd.org (8.8.178.135).
Escape character is '^]'.
larry
Login: lile Name: Larry Lile
Directory: /home/lile Shell: /usr/local/bin/bash
No Mail.
Mail forwarded to: lile@stdio.com
No Plan.
So let's write a little AnyEvent function that makes a finger request:
use AnyEvent;
use AnyEvent::Socket;
sub finger($$) {
my ($user, $host) = @_;
# use a condvar to return results
my $cv = AnyEvent->condvar;
# first, connect to the host
tcp_connect $host, "finger", sub {
# the callback receives the socket handle - or nothing
my ($fh) = @_
or return $cv->send;
# now write the username
syswrite $fh, "$user\015\012";
my $response;
( run in 1.329 second using v1.01-cache-2.11-cpan-39bf76dae61 )