ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/Intro.pod
Revision: 1.1
Committed: Fri May 30 23:17:49 2008 UTC (16 years, 1 month ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 Network Programming with AnyEvent
2    
3     This is a tutorial that will introduce you to AnyEvent by writing a small
4     event-based program.
5    
6     =head2 Introduction
7    
8     AnyEvent is first of all just a framework for multiple event loops. It is
9     a thin abstraction layer above all kinds of event loops. Its main purpose
10     is to move the choice of the event loop (whether it is Glib, Qt, EV or
11     Event, or even something else, see also L<AnyEvent>) from the module
12     author to the program author using the module.
13    
14     A typical problem with modules such as L<Net::IRC> is that they come with
15     their own event loop. In L<Net::IRC>, the program who uses it needs to
16     start the event loop of L<Net::IRC>. That means that one cannot integrate
17     this module into a L<Gtk2> GUI for instance, as that module, too, enforces
18     the use of its own event loop.
19    
20     Another example is L<LWP>: it provides no event interface at all. It's a
21     pure blocking HTTP (and FTP etc.) client library, which usually means that
22     you either have to start a thread or have to fork for a HTTP request, or
23     use L<Coro::LWP>, if you want to do something else while waiting for the
24     request to finish.
25    
26     The motivation behind these designs is often that a module doesn't want to
27     depend on some complicated XS-module (Net::IRC), or that it doesn't want
28     to force the user to use some specific event loop (LWP).
29    
30     L<AnyEvent> solves this dilemma, by B<not> forcing module authors to:
31    
32     =over 4
33    
34     =item 1. Write their own event loop.
35    
36     =item 2. Choose one fixed event loop.
37    
38     =back
39    
40     If the module author uses L<AnyEvent> for all his event needs (IO events, timers,
41     signals, ...) all other modules can just use his module and don't have to choose
42     an event loop or adapt to his event loop. The choice of the event loop is ultimately
43     made by the program author who uses all the modules and writes the main
44     program. And even there he doesn't have to choose, he can just ask L<AnyEvent>
45     to choose any available event loop for him.
46    
47     And while AnyEvent can make good use of event loops written in C, such as
48     EV or Glib, it also comes with a fast pure-perl event loop implementation
49     on its own, which means module authors can rely on AnyEvent without
50     fearing a worrisome dependency on some XS module.
51    
52     Read more about this in the main documentation of the L<AnyEvent> module.
53    
54     =head2 Network programming and AnyEvent
55    
56     However, AnyEvent is not just a simple abstraction anymore. While the core
57     L<AnyEvent> module is still small and self-contained, the distribution
58     comes with some very useful utility modules such as L<AnyEvent::Handle>,
59     L<AnyEvent::DNS> and L<AnyEvent::Socket>. These can make your life as
60     non-blocking network programmer a lot easier.
61    
62     Here is an introduction into these three submodules:
63    
64     =head3 L<AnyEvent::Handle>
65    
66     This module handles non-blocking IO on file handles in an event based
67     manner. It provides a wrapper object around your file handle that provides
68     queueing and buffering of incoming and outgoing data for you.
69    
70     More about this later.
71    
72     =head3 L<AnyEvent::Socket>
73    
74     This module provides you with functions that handle socket creation
75     and IP address magic. The two main functions are C<tcp_connect> and
76     C<tcp_server>. The former will connect a (streaming) socket to an internet
77     host for you and the later will make a server socket for you, to accept
78     connections.
79    
80     This module also comes with transparent IPv6 support, this means: If you
81     write your programs with this module, you will be IPv6 ready without doing
82     anything further.
83    
84     It also works around a lot of portability quirks (especially on the
85     windows platform), which makes it even easier to write your programs in a
86     portable way.
87    
88     =head3 L<AnyEvent::DNS>
89    
90     This module allows fully asynchronous DNS resolution. It is used mainly
91     by L<AnyEvent::Socket> to resolve hostnames and service ports, but is a
92     great way to do other DNS resolution tasks, such as reverse lookups of IP
93     addresses for log files.
94    
95     =head2 First experiments with AnyEvent::Handle
96    
97     Now let's start with something simple: a program that reads from standard
98     input in a non-blocking way, that is, in a way that lets your program do
99     other things while it is waiting for input.
100    
101     First, the full program listing:
102    
103     #!/usr/bin/perl
104    
105     use AnyEvent;
106     use AnyEvent::Handle;
107    
108     my $end_prog = AnyEvent->condvar;
109    
110     my $handle =
111     AnyEvent::Handle->new (
112     fh => \*STDIN,
113     on_eof => sub {
114     print "received EOF, exiting...\n";
115     $end_prog->broadcast;
116     },
117     on_error => sub {
118     print "error while reading from STDIN: $!\n";
119     $end_prog->broadcast;
120     }
121     );
122    
123     $handle->push_read (sub {
124     my ($handle) = @_;
125    
126     if ($handle->rbuf =~ s/^.*?\bend\b.*$//s) {
127     print "got 'end', existing...\n";
128     $end_prog->broadcast;
129     return 1
130     }
131    
132     0
133     });
134    
135     $end_prog->recv;
136    
137     That's a mouthful, so lets go through it step by step:
138    
139     #!/usr/bin/perl
140    
141     use AnyEvent;
142     use AnyEvent::Handle;
143    
144     Nothing unexpected here, just load AnyEvent for the event functionality
145     and AnyEvent::Handle for your file handling needs.
146    
147     my $end_prog = AnyEvent->condvar;
148    
149     Here the program creates a so-called 'condition variable': Condition
150     variables are a great way to signal the completion of some event, or to
151     state that some condition became true (thus the name).
152    
153     This condition variable represents the condition that the program wants to
154     terminate. Later in the progra, we will 'recv' that condition (call the
155     C<recv> method on it), which will wait until the condition gets signalled
156     (which is done by calling the C<send> method on it).
157    
158     The next step is to create the handle object:
159    
160     my $handle =
161     AnyEvent::Handle->new (
162     fh => \*STDIN,
163     on_eof => sub {
164     print "received EOF, exiting...\n";
165     $end_prog->broadcast;
166     },
167    
168     This handle object will read from standard input. Setting the C<on_eof>
169     callback should be done for every file handle, as that is a condition that
170     we always need to check for when working with file handles, to prevent
171     reading or writing to a closed file handle, or getting stuck indefinitely
172     in case of an error.
173    
174     Speaking of errors:
175    
176     on_error => sub {
177     print "error while reading from STDIN: $!\n";
178     $end_prog->broadcast;
179     }
180     );
181    
182     The C<on_error> callback is also not required, but we set it here in case
183     any error happens when we read from the file handle. It is usually a good
184     idea to set this callback and at least print some diagnostic message: Even
185     in our small example an error can happen. More on this later...
186    
187     $handle->push_read (sub {
188    
189     Next we push a general read callback on the read queue, which
190     will wait until we have received all the data we wanted to
191     receive. L<AnyEvent::Handle> has two queues per file handle, a read and a
192     write queue. The write queue queues pending data that waits to be written
193     to the file handle. And the read queue queues reading callbacks. For more
194     details see the documentation L<AnyEvent::Handle> about the READ QUEUE and
195     WRITE QUEUE.
196    
197     my ($handle) = @_;
198    
199     if ($handle->rbuf =~ s/^.*?\bend\b.*$//s) {
200     print "got 'end', existing...\n";
201     $end_prog->broadcast;
202     return 1
203     }
204    
205     0
206     });
207    
208     The actual callback waits until the word 'end' has been seen in the data
209     received on standard input. Once we encounter the stop word 'end' we
210     remove everything from the read buffer and call the condition variable
211     we setup earlier, that signals our 'end of program' condition. And the
212     callback returns with a true value, that signals we are done with reading
213     all the data we were interested in (all data until the word 'end' has been
214     seen).
215    
216     In all other cases, when the stop word has not been seen yet, we just
217     return a false value, to indicate that we are not finished yet.
218    
219     The C<rbuf> method returns our read buffer, that we can directly modify as
220     lvalue. Alternatively we also could have written:
221    
222     if ($handle->{rbuf} =~ s/^.*?\bend\b.*$//s) {
223    
224     The last line will wait for the condition that our program wants to exit:
225    
226     $end_prog->recv;
227    
228     The call to C<recv> will setup an event loop for us and wait for IO, timer
229     or signal events and will handle them until the condition gets sent (by
230     calling its C<send> method).
231    
232     The key points to learn from this example are:
233    
234     =over 4
235    
236     =item * Condition variables are used to start an event loop.
237    
238     =item * How to registering some basic callbacks on AnyEvent::Handle's.
239    
240     =item * How to process data in the read buffer.
241    
242     =back
243