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