设为首页 收藏本站
查看: 905|回复: 0

[经验分享] Perl Curl Multi的使用

[复制链接]

尚未签到

发表于 2017-5-18 09:22:49 | 显示全部楼层 |阅读模式
  Perl利用CURL Multi实现单进程多连接的WEB访问

#!/usr/bin/perl -w
use strict;
use warnings;
use WWW::Curl::Easy;
use WWW::Curl::Multi;
package UrlFetcher;
sub new {
my $option = shift || {};
$option->{MAX_CONN} = 2 unless defined($option->{MAX_CONN});
$option->{CONNECT_TIMEOUT} = 15 unless defined($option->{CONNECT_TIMEOUT});
$option->{READ_TIMEOUT} = 25 unless defined($option->{READ_TIMEOUT});
$option->{CB_URL} = sub{} unless defined($option->{CB_URL});
$option->{CB_RET} = sub{} unless defined($option->{CB_RET});
$option->{CB_WAIT} = sub {sleep(1)} unless defined($option->{CB_WAIT});
my $curls = {};
for (my $i = 1; $i < $option->{MAX_CONN} + 1; $i++) {
$curls->{$i} = WWW::Curl::Easy->new();
}
bless {
OPTION => $option,
CURLM => WWW::Curl::Multi->new(),
IDLE_CURLS => $curls,
BUSY_CURLS => {},
}
}
sub DESTROY {
my $pkg = shift;
foreach my $i (keys(%{$pkg->{IDLE_CURLS}})) {
delete $pkg->{IDLE_CURLS}->{$i};
}
foreach my $i (keys(%{$pkg->{BUSY_CURLS}})) {
delete $pkg->{BUSY_CURLS}->{$i};
}
delete $pkg->{CURLM};
}
sub _prepareCurl {
my $pkg = shift;
my $active_handles = 0;
foreach my $i (keys(%{$pkg->{IDLE_CURLS}})) {
my $req = &{$pkg->{OPTION}->{CB_URL}}();
if (defined($req) && $req) {
my $curl = $pkg->{IDLE_CURLS}->{$i};
delete $pkg->{IDLE_CURLS}->{$i};
my $data = {CURL=>$curl, REQ=>$req};
$data->{REQ}->{HTTP_CODE} = 0;
$data->{REQ}->{HTTP_BODY} = '';
open (my $fileb, ">", \$req->{HTTP_BODY});
$curl->setopt(WWW::Curl::Easy::CURLOPT_WRITEDATA,$fileb);
$curl->setopt(WWW::Curl::Easy::CURLOPT_HEADER, 0);
$curl->setopt(WWW::Curl::Easy::CURLOPT_CONNECTTIMEOUT, $pkg->{OPTION}->{CONNECT_TIMEOUT});
$curl->setopt(WWW::Curl::Easy::CURLOPT_TIMEOUT, $pkg->{OPTION}->{READ_TIMEOUT});
$curl->setopt(WWW::Curl::Easy::CURLOPT_URL, $req->{HTTP_URL});
$curl->setopt(WWW::Curl::Easy::CURLOPT_PRIVATE,$i);
$pkg->{BUSY_CURLS}->{$i} = $data;
$pkg->{CURLM}->add_handle($curl);
$active_handles++;
}else {
last;
}
}
return $active_handles;
}
sub __processResult {
my $pkg = shift;
my $data = shift;
&{$pkg->{OPTION}->{CB_RET}}($data);
}
sub perform {
my $pkg = shift;
my $active_handles = 0;
my $pending_handles = $pkg->_prepareCurl();
$active_handles += $pending_handles;
while ($active_handles) {
my $active_transfers = $pkg->{CURLM}->perform();
if ($active_transfers != $active_handles) {
while (my ($id,$return_value) = $pkg->{CURLM}->info_read()) {
if ($id) {
$active_handles--;
my $data = $pkg->{BUSY_CURLS}->{$id};
delete $pkg->{BUSY_CURLS}->{$id};
$data->{REQ}->{RET} = $return_value;
$data->{REQ}->{HTTP_CODE} = $data->{CURL}->getinfo(WWW::Curl::Easy::CURLINFO_HTTP_CODE);
$pkg->__processResult($data->{REQ});
$pkg->{IDLE_CURLS}->{$id} = $data->{CURL};
}
}
}
$pending_handles = $pkg->_prepareCurl();
&{$pkg->{OPTION}->{CB_WAIT}}() unless ($pending_handles);
$active_handles += $pending_handles;
die("bad items of easy curl") unless ($pkg->{OPTION}->{MAX_CONN} == scalar(keys(%{$pkg->{IDLE_CURLS}})) + scalar(keys(%{$pkg->{BUSY_CURLS}})));
}
}
1;
__END__
=head1 DOCUMENTATION
use UrlFetcher;
$i = 0;
sub cb_url {
my $ret = undef;
$i++;
$ret = {HTTP_URL => 'http://192.168.2.150/lht/lht.txt?idx='.$i, IDX => $i, MY_VALUE => '000',};
sleep(5) unless ($i % 20);
return $ret;
}
sub cb_ret {
my $d = shift;
print 'INDEX: '. $d->{IDX}. "\n";
print 'MY VALUE: '. $d->{MY_VALUE}. "\n";
print 'RET CODE: '. $d->{RET}. "\n";
if ($d->{RET}) {
print "RET MSG: BAD\n";
} else {
print "RET MSG: OK\n";
}
print 'HTTP CODE: '. $d->{HTTP_CODE}. "\n";
print 'HTTP BODY: '. $d->{HTTP_BODY}. "\n";
}
sub cb_wait {
sleep(1);
}
my $opt = {MAX_CONN=>10,
CONNECT_TIMEOUT=>25,
READ_TIMEOUT=>35,
CB_URL=>\&cb_url,
CB_RET=>\&cb_ret,
CB_WAIT=>\&cb_wait,
};
my $fetcher = UrlFetcher::new($opt);
$fetcher->perform();

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-378639-1-1.html 上篇帖子: apache1.3.4 & mod_perl & mod_ssl 下篇帖子: perl-stat和lstat
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表