使用 perl、wsdl 和多线程的 Web 服务不起作用:
- 使用线程执行命令行:有效
- 带有线程的肥皂客户端调用:不起作用
- 没有线程的肥皂客户端调用:有效
在这里,我尝试使用线程更新数千个筛子文件,但如果我使用线程,它不起作用。我正在尝试使用 perl 快速制作 web 服务,目前它是用 php 编写的,但是使用 web 服务的线程不起作用任何帮助都会有所帮助。
当我从肥皂客户端(soap_client.pl)调用 Web 服务时,它返回以下错误。
500 Server closed connection without sending any data back
安装的 perl 模块:
MIME::Parser
SOAP::Lite
阿帕奇模块:
mod_perl
阿帕奇虚拟主机:
<VirtualHost 192.168.1.187:80>
ServerName sieve.net
ServerAlias www.sieve.net
DocumentRoot /web/sieve.net/htdocs
ErrorLog /var/log/httpd/sieve.net_error_log
TransferLog /var/log/httpd/sieve.net_access_log
<Directory "/web/sieve.net/htdocs">
<FilesMatch "\.mhtml$|\.pl$|\.html$">
Options +ExecCGI
AddHandler cgi-script .cgi .pl .html
SetHandler perl-script
PerlHandler ModPerl::Registry
PerlSendHeader On
</FilesMatch>
</Directory>
DirectoryIndex index.phtml index.htm index.html index.pl
</VirtualHost>
sievefilter_thread.pl
#!/usr/bin/perl
use strict;
use SOAP::Lite;
use SOAP::Transport::HTTP;
use lib "/web/sieve.net/htdocs";
use Sieve;
use threads;
use Thread::Queue;
my $soap = SOAP::Transport::HTTP::CGI->new(
dispatch_to => 'manageSieve'
);
$soap->handle();
package manageSieve;
sub updateSieveFilter {
my ($package, $client_id) = @_;
my @users = ({
'Password' => 'test',
'Login' => 'test1@example.in'
},
{
'Password' => 'test',
'Login' => 'test2@example.in'
},
{
'Password' => 'test',
'Login' => 'test3@example.in'
},
{
'Password' => 'test',
'Login' => 'test4@example.in'
},
{
'Password' => 'test',
'Login' => 'test5@example.in'
},
);
if(@users) {
my $THREADS = 30;
my $Qwork = new Thread::Queue;
my $Qresults = new Thread::Queue;
# If i return any value from here it wokrs.
## Create the pool of workers
my @pool = map{
threads->create( \&updateClientUsersSieve, $Qwork, $Qresults )
} 1 .. $THREADS;
# Does not return any value from here.
foreach my $user (@users){
$Qwork->enqueue( $user );
if( $counter % 100 == 0){
sleep 1;
}
$counter++;
}
$Qwork->enqueue( (undef) x $THREADS );
## Process the results as they become available
for ( 1 .. $THREADS ) {
while( $result = $Qresults->dequeue ) {
#print $result;
}
}
# Clean up the threads
$_->join for @pool;
return 1;
}
return 0;
}
sub updateClientUsersSieve {
my $tid = threads->tid;
my $result = 1;
my( $Qwork, $Qresults ) = @_;
my ($login, $password);
while( my $user = $Qwork->dequeue ) {
($login, $password) = ($user->{'Login'}, $user->{'Password'});
my $sieveObj = new Sieve($login, $password);
$result = $sieveObj->sieveLogin();
$Qresults->enqueue( $result );
}
$Qresults->enqueue( undef ); ## Signal this thread is finished
}
1;
筛分.pm
#!/usr/bin/perl
package Sieve;
use Net::ManageSieve;
use strict;
sub new {
my $class = shift;
my $self = {
_username => shift,
_password => shift,
_sieve => undef,
};
bless $self, $class;
return $self;
}
sub sieveLogin {
my ($self) = @_;
my $sieveServer = 'localhost';
my $sievePort = 2000;
my $authType = 'PLAIN';
my $username = $self->{_username};
my $password = $self->{_password};
my $capabilities = "require [";
my $activescript = "";
my $script_name = "sievephp_testscript";
my $error = undef;
$self->{_sieve} = Net::ManageSieve->new("$sieveServer:$sievePort");
if(!$self->{_sieve}->login($username, $password)){
return 0;
}
$capabilities = $self->{_sieve}->capabilities->{sieve};
$capabilities =~ s/\s/\",\"/g;
$capabilities = 'require ["'.$capabilities.'"];'."\n";
$activescript = $capabilities;
$activescript .= "\n";
$activescript .= "if allof (size :over 1000K ){ reject text: Your mail Has been rejected due to mailsize control\n\n.;";
$activescript .= "stop;}";
$self->{_sieve}->putscript($script_name, $activescript);
$self->{_sieve}->logout;
return 1;
}
1;
筛子.wsdl
<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="urn:manageSieve" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloService" targetNamespace="urn:manageSieve" xmlns:y="urn:manageSieve">
<message name="updateSieveFilterRequest">
<part name="client_code" type="xsd:string"/>
</message>
<message name="updateSieveFilterResponse">
<part name="Result" type="xsd:string"/>
</message>
<portType name="Hello_PortType">
<operation name="updateSieveFilter">
<input message="tns:updateSieveFilterRequest"/>
<output message="tns:updateSieveFilterResponse"/>
</operation>
</portType>
<binding name="Hello_Binding" type="tns:Hello_PortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="updateSieveFilter">
<soap:operation soapAction="urn:manageSieve#updateSieveFilter"/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:manageSieve" use="encoded"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:manageSieve" use="encoded"/>
</output>
</operation>
</binding>
<service name="Hello_Service">
<documentation>WSDL File for HelloService</documentation>
<port binding="tns:Hello_Binding" name="Hello_Port">
<soap:address location="http://sieve.net/sievefilter_thread.pl"/>
</port>
</service>
</definitions>
肥皂客户端.pl
use SOAP::Lite;
my $client = SOAP::Lite->service("http://sieve.net/sieve.wsdl");
my $result = $client->updateSieveFilter(17);
print $result;