… | |
… | |
392 | |
392 | |
393 | =head1 Network programming and AnyEvent |
393 | =head1 Network programming and AnyEvent |
394 | |
394 | |
395 | So far you have seen how to register event watchers and handle events. |
395 | So far you have seen how to register event watchers and handle events. |
396 | |
396 | |
397 | This is a great basis to write network clients and servers, and might be |
397 | This is a great foundation to write network clients and servers, and might be |
398 | all that your module (or program) ever requires, but writing your own I/O |
398 | all that your module (or program) ever requires, but writing your own I/O |
399 | buffering again and again becomes tedious, not to mention that it attracts |
399 | buffering again and again becomes tedious, not to mention that it attracts |
400 | errors. |
400 | errors. |
401 | |
401 | |
402 | While the core L<AnyEvent> module is still small and self-contained, |
402 | While the core L<AnyEvent> module is still small and self-contained, |
… | |
… | |
527 | $cv |
527 | $cv |
528 | } |
528 | } |
529 | |
529 | |
530 | This isn't too complicated, just a function with two parameters, which |
530 | This isn't too complicated, just a function with two parameters, which |
531 | creates a condition variable, returns it, and while it does that, |
531 | creates a condition variable, returns it, and while it does that, |
532 | initiates a TCP connect to the passed C<$host>. The condition variable |
532 | initiates a TCP connect to C<$host>. The condition variable |
533 | will be used by the caller to receive the finger response. |
533 | will be used by the caller to receive the finger response. |
534 | |
534 | |
535 | Since we are event-based programmers, we do not wait for the connect to |
535 | Since we are event-based programmers, we do not wait for the connect to |
536 | finish - it could block your program for a minute or longer! |
536 | finish - it could block your program for a minute or longer! Instead, |
537 | |
537 | we pass the callback it should invoke when the connect is done to |
538 | Instead, we pass C<tcp_connect> the callback it should invoke when the |
538 | C<tcp_connect>. If it is successful, our callback gets called with the |
539 | connect is done. If it is successful, our callback gets passed the socket |
|
|
540 | handle as first argument, otherwise, nothing will be passed. |
539 | socket handle as first argument, otherwise, nothing will be passed to our |
|
|
540 | callback. |
541 | |
541 | |
542 | Let's look at our callback in more detail: |
542 | Let's look at our callback in more detail: |
543 | |
543 | |
544 | # the callback gets the socket handle - or nothing |
544 | # the callback gets the socket handle - or nothing |
545 | my ($fh) = @_ |
545 | my ($fh) = @_ |
546 | or return $cv->send; |
546 | or return $cv->send; |
547 | |
547 | |
548 | The first thing the callback does is indeed save the passed socket handle |
548 | The first thing the callback does is indeed save the socket handle in |
549 | in C<$fh>. When there was an error (no arguments), then our instinct would |
549 | C<$fh>. When there was an error (no arguments), then our instinct as |
550 | tell us to die: |
550 | expert Perl programmers would tell us to die: |
551 | |
551 | |
552 | my ($fh) = @_ |
552 | my ($fh) = @_ |
553 | or die "$host: $!"; |
553 | or die "$host: $!"; |
554 | |
554 | |
555 | While this would give good feedback to the user, our program would |
555 | While this would give good feedback to the user, our program would |
… | |
… | |
584 | poll => "r", |
584 | poll => "r", |
585 | |
585 | |
586 | There is a trick here, however: the read watcher isn't stored in a global |
586 | There is a trick here, however: the read watcher isn't stored in a global |
587 | variable, but in a local one - if the callback returns, it would normally |
587 | variable, but in a local one - if the callback returns, it would normally |
588 | destroy the variable and its contents, which would in turn unregister our |
588 | destroy the variable and its contents, which would in turn unregister our |
589 | watcher again. |
589 | watcher. |
590 | |
590 | |
591 | To avoid that, we C<undef>ine the variable in the watcher callback. This |
591 | To avoid that, we C<undef>ine the variable in the watcher callback. This |
592 | means that, when the C<tcp_connect> callback returns, that Perl thinks |
592 | means that, when the C<tcp_connect> callback returns, that perl thinks |
593 | (quite correctly) that the read watcher is still in use - namely in the |
593 | (quite correctly) that the read watcher is still in use - namely in the |
594 | callback. |
594 | callback. |
595 | |
595 | |
596 | The callback itself calls C<sysread> for as many times as necessary, until |
596 | The callback itself calls C<sysread> for as many times as necessary, until |
597 | C<sysread> returns an error or end-of-file: |
597 | C<sysread> returns an error or end-of-file: |
… | |
… | |
614 | gets destroyed as well. The result is that all resources will be nicely |
614 | gets destroyed as well. The result is that all resources will be nicely |
615 | cleaned up by perl for us. |
615 | cleaned up by perl for us. |
616 | |
616 | |
617 | =head3 Using the finger client |
617 | =head3 Using the finger client |
618 | |
618 | |
619 | Now, we could probably write the same finger client simpler if we used |
619 | Now, we could probably write the same finger client in a simpler way if |
620 | C<IO::Socket::INET>, ignored the problem of multiple hosts and ignored |
620 | we used C<IO::Socket::INET>, ignored the problem of multiple hosts and |
621 | IPv6 and a few other things. |
621 | ignored IPv6 and a few other things that C<tcp_connect> handles for us. |
622 | |
622 | |
623 | But the main advantage is that we can not only run this finger function in |
623 | But the main advantage is that we can not only run this finger function in |
624 | the background, we even can run multiple sessions in parallel, like this: |
624 | the background, we even can run multiple sessions in parallel, like this: |
625 | |
625 | |
626 | my $f1 = finger "trouble", "noc.dfn.de"; # check for trouble tickets |
626 | my $f1 = finger "trouble", "noc.dfn.de"; # check for trouble tickets |
… | |
… | |
630 | print "trouble tickets:\n", $f1->recv, "\n"; |
630 | print "trouble tickets:\n", $f1->recv, "\n"; |
631 | print "trouble ticket #1736:\n", $f2->recv, "\n"; |
631 | print "trouble ticket #1736:\n", $f2->recv, "\n"; |
632 | print "john carmacks finger file: ", $f3->recv, "\n"; |
632 | print "john carmacks finger file: ", $f3->recv, "\n"; |
633 | |
633 | |
634 | It doesn't look like it, but in fact all three requests run in |
634 | It doesn't look like it, but in fact all three requests run in |
635 | parallel. The code waits for the first finger request to finish first, but |
635 | parallel. The code waits for the first finger request to finish first, |
636 | that doesn't keep it from executing all three in parallel. |
636 | but that doesn't keep it from executing all three in parallel, a bug time |
|
|
637 | saver. |
|
|
638 | |
|
|
639 | By the way, you do not actually have to wait in the C<recv> method on an |
|
|
640 | AnyEvent condition variable, you can also register a callback: |
|
|
641 | |
|
|
642 | $cv->cb (sub { |
|
|
643 | my $response = shift->recv; |
|
|
644 | # ... |
|
|
645 | }); |
|
|
646 | |
|
|
647 | The callback will only be invoked when C<send> was called. In fact, |
|
|
648 | instead of returning a condition variable you could also pass a third |
|
|
649 | parameter to your finger function, the callback to invoke with the |
|
|
650 | response: |
|
|
651 | |
|
|
652 | sub finger($$$) { |
|
|
653 | my ($user, $host, $cb) = @_; |
|
|
654 | |
|
|
655 | What you use is a matter of taste - if you expect your function to be |
|
|
656 | used mainly in an event-based program you would normally prefer to pass a |
|
|
657 | callback directly. |
637 | |
658 | |
638 | =head3 Criticism and fix |
659 | =head3 Criticism and fix |
639 | |
660 | |
640 | To make this example more real-world-ready, we would not only implement |
661 | To make this example more real-world-ready, we would not only implement |
641 | some write buffering (for the paranoid), but we would also have to handle |
662 | some write buffering (for the paranoid), but we would also have to handle |