# NAME AnyEvent::MultiDownload - éžé˜»å¡žçš„多线程多地å€æ–‡ä»¶ä¸‹è½½çš„æ¨¡å— # SYNOPSIS 这是一个全éžé˜»å¡žçš„多线程多地å€æ–‡ä»¶ä¸‹è½½çš„模å—, å¯ä»¥è±¡ä¸‹é¢è¿™ä¸ªåº”ç”¨ä¸€æ ·, åŒæ—¶ä¸‹è½½å¤šä¸ªæ–‡ä»¶, 并且整个过程都是异æ¥äº‹ä»¶è§£å‘, ä¸ä¼šé˜»å¡žä¸»è¿›ç¨‹. 下é¢æ˜¯ä¸ªç®€å•çš„例å, åŒæ—¶ä»Žå¤šä¸ªåœ°å€ä¸‹è½½åŒä¸€ä¸ªæ–‡ä»¶. use AE; use AnyEvent::MultiDownload; my @urls = ( 'http://mirrors.163.com/centos/7/isos/x86_64/CentOS-7.0-1406-x86_64-DVD.iso', 'http://mirrors.sohu.com/centos/7/isos/x86_64/CentOS-7.0-1406-x86_64-DVD.iso', ); my $cv = AE::cv; my $MultiDown = AnyEvent::MultiDownload->new( url => pop @urls, mirror => \@urls, path => '/tmp/ubuntu.iso', block_size => 1 * 1024 * 1024, # 1M on_block_finish => sub { my ($hdr, $block_obj, $md5) = @_; if ($md5 eq $src_md5) { return 1; } 0 }, on_finish => sub { my $len = shift; $cv->send; }, on_error => sub { my ($error, $hdr) = @_; $cv->send; } )->start; $cv->recv; 下é¢æ˜¯å¼‚æ¥åŒæ—¶ä¸‹è½½å¤šä¸ªæ–‡ä»¶çš„实例. 整个过程异æ¥. use AE; use AnyEvent::MultiDownload; my $cv = AE::cv; $cv->begin; my $MultiDown = AnyEvent::MultiDownload->new( url => 'http://xxx/file1', path => "/tmp/file2", on_finish => sub { my $len = shift; $cv->end; }, on_error => sub { my ($error, $hdr) = @_; $cv->end; } ); $MultiDown->start; $cv->begin; my $MultiDown1 = AnyEvent::MultiDownload->new( url => 'http://xxx/file2', path => "/tmp/file1", on_finish => sub { my $len = shift; $cv->end; }, on_error => sub { my ($error, $hdr) = @_; $cv->end; } ); $MultiDown1->start; $cv->recv; 以上是åŒæ—¶ä¸‹è½½å¤šä¸ªæ–‡ä»¶çš„实例. 这个过程有其它的事件并ä¸ä¼šé˜»å¡ž. # 属性 ## url 下载的主地å€, 这个是下载用的 master 的地å€, 是主地å€, 这个å‚数必须有. ## path 下载åŽçš„å˜æ”¾åœ°å€, 这个地å€ç”¨äºŽæŒ‡å®š, 下载完了, å˜æ”¾åœ¨ä»€ä¹ˆä½ç½®. 这个å‚数必须有. ## mirror 文件下载的镜象地å€, 这个是å¯ä»¥ç”¨æ¥åšå¤‡ç”¨åœ°å€å’Œåˆ†å—下载时用的地å€. 需è¦ä¸€ä¸ªæ•°ç»„引用, å…¶ä¸æ”¾å…¥è¿™ä¸ªæ–‡ä»¶çš„其它用于下载的地å€. 如果å—下载失败会自动切æ¢æˆå…¶å®ƒçš„地å€ä¸‹è½½. 本å‚æ•°ä¸æ˜¯å¿…须的. ## block\_size 下载å—的大å°, 默认这个 block\_size 是指æ¯æ¬¡å–å—的大å°, 默认是 1M 一个å—, 这个å‚数会给文件按照 1M 的大å°æ¥åˆ‡æˆä¸€ä¸ªä¸ªå—æ¥ä¸‹è½½å¹¶åˆå¹¶. 本å‚æ•°ä¸æ˜¯å¿…须的. ## digest 用于指定所使用的å—较检所使用的模å—, æ”¯æŒ Digest::MD5 å’Œ Digest::SHA1 ## retry\_interval é‡è¯•çš„é—´éš”, 默认为 10 s. ## max\_retries é‡è¯•æ¯ä¸ªå—所能é‡è¯•çš„次数, 默认为 3 次. ## max\_per\_host æ¯ä¸ªæ–‡ä»¶æœ€å¤šå‘出去的连接数é‡. ## headers å¦‚æžœä½ æƒ³è‡ªå·±å®šä¹‰ä¼ é€çš„ header , 就在这个å‚æ•°ä¸åŠ 就好了, 默认是一个哈希引用. ## timeout 下载多久算超时, å¯é€‰å‚æ•°, 默认为 10s. ## recurse é‡å®šå‘ 如果请求过程ä¸æœ‰é‡å®šå‘, å¯ä»¥æœ€å¤šé‡å®šå‘多少次. ## content\_file DEPRECATED 这个属性被替æ¢æˆ path # METHODS ## start() 事件开始的方法. åªæœ‰è°ƒç”¨è¿™ä¸ªå‡½æ•°æ—¶, 这个下载的事件æ‰å¼€å§‹æ‰§è¡Œ. ## multi\_get\_file() DEPRECATED 这个方å¼æ›¿æ¢æˆ start 了 # 回调 ## on\_block\_finish 当æ¯ä¸‹è½½å®Œ 1M æ—¶, 会回调一次, ä½ å¯ä»¥ç”¨äºŽæ£€æŸ¥ä½ 的下载æ¯å—的完整性, 这个时候åªæœ‰ 200 å’Œ 206 å“应的时候æ‰ä¼šå›žè°ƒ. å›žè°ƒä¼ å››ä¸ªå‚æ•°, 本å—下载时å“应的 header, 当å‰å—çš„ä¿¡æ¯çš„引用 ( åŒ…å« block ç¬¬å‡ å—, size 下载å—的大å°, pos å—的开始ä½ç½® ), 检查的 md5 或者 sha1 的结果. 这个需è¦è¿”回值, 如果值为 1 è¯æ˜Žæ£€æŸ¥ç»“æžœæ£å¸¸, 如果为 0 è¯æ˜Žæ£€æŸ¥å¤±è´¥. 默认模å—会帮助检查大å°, 所以大å°ä¸ç”¨å¯¹æ¯”和检查了, è¿™ä¸ªåœ°æ–¹ä¼šæ ¹æ® $self->digest 指定的信æ¯, ç»™æ¯å—çš„ MD5 或者 SHA1 记录下æ¥, 使用这个æ¥å¯¹æ¯”. 本å‚æ•°ä¸æ˜¯å¿…须的. 如果没有这个回调默认检查大å°æ£ç¡®. ## on\_finish 当整个文件下载完æˆæ—¶çš„回调, 下载完æˆçš„å›žè°ƒä¼šä¼ ä¸€ä¸ªä¸‹è½½çš„æ–‡ä»¶å¤§å°çš„å‚数过æ¥. 这个回调必须å˜åœ¨. ## on\_error 当整个文件下载过程出错时回调, 这个å‚æ•°å¿…é¡»å˜åœ¨, å› ä¸ºä¸èƒ½ä¿è¯æ¯æ¬¡ä¸‹è½½éƒ½èƒ½æ£å¸¸. ## on\_seg\_finish DEPRECATED 这个回调被替æ¢æˆ on\_block\_finish 回调了. # SEE ALSO [AnyEvent](https://metacpan.org/pod/AnyEvent), [AnyEvent::HTTP](https://metacpan.org/pod/AnyEvent::HTTP), [App::ManiacDownloader](https://metacpan.org/pod/App::ManiacDownloader). # AUTHOR 扶凯 fukai <iakuf@163.com>