… | |
… | |
443 | to your program? That C<WSAEINPROGRESS> means your C<connect> call was |
443 | to your program? That C<WSAEINPROGRESS> means your C<connect> call was |
444 | ignored instead of being in progress? AnyEvent::Socket works around all of |
444 | ignored instead of being in progress? AnyEvent::Socket works around all of |
445 | these Windows/Perl bugs for you). |
445 | these Windows/Perl bugs for you). |
446 | |
446 | |
447 | =head2 Implementing a parallel finger client with non-blocking connects |
447 | =head2 Implementing a parallel finger client with non-blocking connects |
|
|
448 | and AnyEvent::Socket |
448 | |
449 | |
449 | The finger protocol is one of the simplest protocols in use on the |
450 | The finger protocol is one of the simplest protocols in use on the |
450 | internet. Or in use in the past, as almost nobody uses it anymore. |
451 | internet. Or in use in the past, as almost nobody uses it anymore. |
451 | |
452 | |
452 | It works by connecting to the finger port on another host, writing a |
453 | It works by connecting to the finger port on another host, writing a |
… | |
… | |
1013 | Specifying C<tls> enables TLS, and the argument specifies whether |
1014 | Specifying C<tls> enables TLS, and the argument specifies whether |
1014 | AnyEvent::Handle is the server side ("accept") or the client side |
1015 | AnyEvent::Handle is the server side ("accept") or the client side |
1015 | ("connect") for the TLS connection, as unlike TCP, there is a clear |
1016 | ("connect") for the TLS connection, as unlike TCP, there is a clear |
1016 | server/client relationship in TLS. |
1017 | server/client relationship in TLS. |
1017 | |
1018 | |
|
|
1019 | That's all. |
|
|
1020 | |
1018 | That's all. Of course, all this should be handled transparently by |
1021 | Of course, all this should be handled transparently by C<http_get> after |
1019 | C<http_get> after parsing the URL. See the part about exercising your |
1022 | parsing the URL. See the part about exercising your inspiration earlier in |
1020 | inspiration earlier in this document. |
1023 | this document. |
1021 | |
1024 | |
1022 | =head3 The read queue - revisited |
1025 | =head3 The read queue - revisited |
1023 | |
1026 | |
1024 | HTTP always uses the same structure in its responses, but many protocols |
1027 | HTTP always uses the same structure in its responses, but many protocols |
1025 | require parsing responses different depending on the response itself. |
1028 | require parsing responses different depending on the response itself. |
… | |
… | |
1067 | |
1070 | |
1068 | $handle->push_read (line => $read_response); |
1071 | $handle->push_read (line => $read_response); |
1069 | |
1072 | |
1070 | This recipe can be used for all similar parsing problems, for example in |
1073 | This recipe can be used for all similar parsing problems, for example in |
1071 | NNTP, the response code to some commands indicates that more data will be |
1074 | NNTP, the response code to some commands indicates that more data will be |
1072 | sent. |
1075 | sent: |
1073 | |
1076 | |
1074 | =head1 AUTHORS |
1077 | $handle->push_write ("article 42"); |
|
|
1078 | |
|
|
1079 | # read response line |
|
|
1080 | $handle->push_read (line => sub { |
|
|
1081 | my ($handle, $status) = @_; |
|
|
1082 | |
|
|
1083 | # article data following? |
|
|
1084 | if ($status =~ /^2/) { |
|
|
1085 | # yes, read article body |
|
|
1086 | |
|
|
1087 | $handle->unshift_read (line => "\012.\015\012", sub { |
|
|
1088 | my ($handle, $body) = @_; |
|
|
1089 | |
|
|
1090 | $finish->($status, $body); |
|
|
1091 | }); |
|
|
1092 | |
|
|
1093 | } else { |
|
|
1094 | # some error occured, no article data |
|
|
1095 | |
|
|
1096 | $finish->($status); |
|
|
1097 | } |
|
|
1098 | } |
|
|
1099 | |
|
|
1100 | =head3 Your own read queue handler |
|
|
1101 | |
|
|
1102 | Sometimes, your protocol doesn't play nice and uses lines or chunks of |
|
|
1103 | data, in which case you have to implement your own read parser. |
|
|
1104 | |
|
|
1105 | To make up a contorted example, imagine you are looking for an even |
|
|
1106 | number of characters followed by a colon (":"). Also imagine that |
|
|
1107 | AnyEvent::Handle had no C<regex> read type which could be used, so you'd |
|
|
1108 | had to do it manually. |
|
|
1109 | |
|
|
1110 | To implement this, you would C<push_read> (or C<unshift_read>) just a |
|
|
1111 | single code reference. |
|
|
1112 | |
|
|
1113 | This code reference will then be called each time there is (new) data |
|
|
1114 | available in the read buffer, and is expected to either eat/consume some |
|
|
1115 | of that data (and return true) or to return false to indicate that it |
|
|
1116 | wants to be called again. |
|
|
1117 | |
|
|
1118 | If the code reference returns true, then it will be removed from the read |
|
|
1119 | queue, otherwise it stays in front of it. |
|
|
1120 | |
|
|
1121 | The example above could be coded like this: |
|
|
1122 | |
|
|
1123 | $handle->push_read (sub { |
|
|
1124 | my ($handle) = @_; |
|
|
1125 | |
|
|
1126 | # check for even number of characters + ":" |
|
|
1127 | # and remove the data if a match is found. |
|
|
1128 | # if not, return false (actually nothing) |
|
|
1129 | |
|
|
1130 | $handle->{rbuf} =~ s/^( (?:..)* ) ://x |
|
|
1131 | or return; |
|
|
1132 | |
|
|
1133 | # we got some data in $1, pass it to whoever wants it |
|
|
1134 | $finish->($1); |
|
|
1135 | |
|
|
1136 | # and return true to indicate we are done |
|
|
1137 | 1 |
|
|
1138 | }); |
|
|
1139 | |
|
|
1140 | |
|
|
1141 | =head1 Authors |
1075 | |
1142 | |
1076 | Robin Redeker C<< <elmex at ta-sa.org> >>, Marc Lehmann <schmorp@schmorp.de>. |
1143 | Robin Redeker C<< <elmex at ta-sa.org> >>, Marc Lehmann <schmorp@schmorp.de>. |
1077 | |
1144 | |