ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/doc/Tutorial.pod
Revision: 1.4
Committed: Fri May 30 23:17:49 2008 UTC (15 years, 11 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +0 -0 lines
State: FILE REMOVED
Log Message:
*** empty log message ***

File Contents

# Content
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