我正在使用Perl(5.8.7)从Linux调用.net webservice。 我正在使用SOAP :: Lite库。
概念的基本证明工作得很好,现在我在现实世界中尝试它,我必须多次调用web服务。现在看起来Web服务调用打开了一个文件,但是没有释放文件描述符。默认的最大可用数量设置为256,并且在程序死亡之后很快就会出现这种情况。 :(
以下是代码:
# Create the soap client
my $client = SOAP::Lite->new;
# Get raw SOAP xml output
$client->outputxml(1);
# Set connection parameters
$client->uri($namespace);
# set the url in the proxy member. The keep_alive parameter is needed if user authentication
# is used, it is passed on to the user agent class to set up an authenticated HTTP session
$client->proxy($url, keep_alive => 1);
# Set the user credentials
$client->transport->credentials("$host:$port", ''
, $user
, $password
);
# define the webservice method
$client->on_action( sub { return "$namespace$method" } );
my $soapmethod = SOAP::Data->name($method)
->attr({xmlns => $namespace});
# Generate the SOAP parameters and make the call
my @paramarray = ( \%paramhash );
my $ps = ${MakeSoapParameters(\@paramarray)};
# output the current number of filedescriptors used for this process
system("ls -l /proc/$$/fd | wc -l");
# Make the call
my $result = $client->call($soapmethod => $ps );
# output the current number of filedescriptors used for this process AFTER the call
system("ls -l /proc/$$/fd | wc -l");
如果我监视与ls -l / proc / $$ / fd |一起使用的文件描述符wc -l我注意到每次拨打网络服务电话时使用的文件描述符的数量都会增加。
任何帮助或提示都将不胜感激。
答案 0 :(得分:0)
我无法轻易测试,但尝试删除创建的SOAP对象。或者将这段代码包装在一个函数中,这样当它超出范围时,会自动调用析构函数。
答案 1 :(得分:0)
我认为这些文件描述符是套接字,通常系统关闭TCP套接字需要一些时间。
答案 2 :(得分:0)
解决了它。
除了我需要在Perl中了解更多关于对象创建,实例和破坏的事实......
只要创建SOAP :: Lite对象一次并保持它,只要我需要调用该Web服务,就可以了。在为每次调用创建SOAP :: Lite对象之前
大家都感谢你和我一起思考。
my $client;
sub MakeTheCall
{
if (! defined $client)
{
# Create the soap client
my $client = SOAP::Lite->new;
# Get raw SOAP xml output
$client->outputxml(1);
# Set connection parameters
$client->uri($namespace);
# set the url in the proxy member. The keep_alive parameter is needed if user authentication
# is used, it is passed on to the user agent class to set up an authenticated HTTP session
$client->proxy($url, keep_alive => 1);
# Set the user credentials
$client->transport->credentials("$host:$port", ''
, $user
, $password);
}
# rest of the code here
}