SoapFault异常:无法连接到主机

时间:2010-11-30 21:29:22

标签: php soap

有时无法调用Web服务。

这个问题一直在发生。

可能是什么问题?

Error:
    SoapFault exception: [HTTP] Could not connect to host in 
    0 [internal function]: SoapClient->__doRequest('<?xml version="...', http://.', '', 1, 0)

27 个答案:

答案 0 :(得分:26)

问题解决了。问题是缓存

ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);

答案 1 :(得分:20)

我正在添加我对完整性的评论,因为此处列出的解决方案对我没有帮助。在PHP 5.6上,SoapClient首先调用SoapClient::SoapClient中指定的WSDL URL,并在连接到它并接收结果后,尝试连接到结果中指定的WSDL:

<soap:address location="http://"/>

如果WSDL与您在Could not connect to host中指定的WSDL不同并且无法访问(我的情况是使用http://host.local/的SoapUI),则调用失败并返回错误SoapClient::SoapClient

PHP 5.4中的行为不同,它始终使用SoapClient::SoapClient中的WSDL。

答案 2 :(得分:12)

主机要么停机要么响应很慢。如果响应缓慢,您可以尝试通过connection_timeout选项或default_socket_timeout设置增加超时,看看是否可以减少失败。

http://www.php.net/manual/en/soapclient.soapclient.php

http://www.php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout

您还可以包含错误处理,因为zanlok指出要重试几次。如果您的用户实际上在等待这些SOAP调用,那么您将需要将它们排队并在后台处理它们并在用户完成时通知用户。

答案 3 :(得分:8)

php.ini文件中有一个soap配置部分,它控制着wsdl访问缓存,可能显示为:

[soap] 
; Enables or disables WSDL caching feature. 
soap.wsdl_cache_enabled=1 ; 
Sets the directory name where SOAP extension will put cache files. 
soap.wsdl_cache_dir="/tmp" 
; (time to live) Sets the number of second while cached file will be used ; instead of original one.  
soap.wsdl_cache_ttl=86400

如果启用了wsdl文件缓存,则在更改php代码中的wsdl URI时可能会导致此问题。 在此示例中,您只需删除wsdl-目录下/tmp的文件开头即可。 或者您只需设置soap.wsdl_cache_enabled=0;soap.wsdl_cache_ttl=0; 每次访问页面时,PHP都会获取wsdl文件。

答案 4 :(得分:4)

misconfigured服务使用 tempuri.org

离开默认命名空间

这意味着与wsdl的连接将起作用,但函数调用将失败。

  

Stacktrace:

     

SoapClient-&gt; __ doRequest('http://example.com ...','http://tempuri.org ....',2,0)

要修复此问题,您必须使用__setLocation()

明确设置位置
$this->soapClient = new \SoapClient(WS_URL);
$this->soapClient->__setLocation(WS_URL);

答案 5 :(得分:4)

我自己也遇到了这个问题,经过多次挖掘后我终于找到了ubuntu的这个bug:

https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371

具体地

https://bugs.launchpad.net/ubuntu/+source/openssl/+bug/965371/comments/62

openssl s_client -connect site.tld:443失败,但openssl s_client -tls1 -connect site.tld:443取得了成功。在我的特定情况下,包括输出的一部分 New, TLSv1/SSLv3, Cipher is RC4-MD5所以我适当地设置了php上下文ssl / cipher值。

答案 6 :(得分:3)

似乎错误SoapFault exception: Could not connect to host可能会导致几个不同的事情。在我的情况下,它不是由代理,防火墙或DNS造成的(我实际上是使用nusoap工作的同一台机器上的SOAP连接而没有任何特殊设置。)

最后我发现它是由我在SoapClient构造函数的pem选项中引用的无效local_cert文件引起的。

<强>解决方案: 当我从pem文件中删除证书链,因此包含证书和私钥时,SOAP调用开始通过。

答案 7 :(得分:3)

在我的情况下,它在连接到wsdl后工作,使用函数__setLocation()再次定义位置,因为调用失败并显示错误:

  

无法连接到主机

如果WSDL与SoapClient::SoapClient中指定的WSDL不同,则会发生这种情况。

答案 8 :(得分:3)

在我们的案例中,这是一个密码协商问题。我们随机得到了这个错误。我们通过强制这样的密码解决了我们的问题:

$soapClient = new SoapClient('http://example.com/soap.asmx?wsdl',array("stream_context" => stream_context_create(array('ssl' => array('ciphers'=>'AES256-SHA')))));

看起来PHP并没有在每个服务电话上协商相同的密码。

答案 9 :(得分:2)

这项工作对我来说

$opts = array(
  'ssl' => array('verify_peer' => false, 'verify_peer_name' => false)
);

if (!isset($this->soap_client)) {
  $this->soap_client = new SoapClient($this->WSDL, array(
    'soap_version'   => $this->soap_version,
    'location'       => $this->URL,
    'trace'          => 1,
    'exceptions'     => 0,
    'stream_context' => stream_context_create($opts)
  ));

答案 10 :(得分:2)

我终于找到了原因,因为图书馆无法在您的系统上找到CA捆绑包。 默认情况下,PHP&gt; = v5.6会自动将 verify_peer 设置为true。但是,并非所有系统都在磁盘上具有已知的CA捆绑包。

您可以尝试以下程序之一:

1.如果您的系统上有CA文件,请将openssl.cafile中的curl.cainfophp.ini设置为CA文件的路径。

2.手动指定您的SSL CA文件位置

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);  
curl_setopt($cHandler, CURLOPT_CAINFO, $path-of-your-ca-file);

3.disabled verify_peer

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

答案 11 :(得分:1)

此错误的另一个可能原因是在创建并保持太多连接打开时。

默认情况下,SoapClient发送HTTP标头table.setItems(data); (通过构造函数选项Connection: Keep-Alive)。但是,如果您为队列中的每个呼叫创建一个新的SoapClient实例,则这将每次创建并保持打开状态。如果调用执行得足够快,您最终将遇到约1000个打开的连接的限制,这将导致keep_alive

因此,请确保创建一次SoapClient,并将其重新用于后续调用。

答案 12 :(得分:1)

对于那些使用laravel artisan控制台命令与我一样挣扎的人,该命令对外部soap服务器的同一wsdl发出很多请求,但一段时间后失败,并显示Could not connect to host错误。

问题是因为每次发出请求之前,我都在创建新的SoapClient实例。不要那样做。创建一次,并从同一客户端发出每个请求。

希望有帮助。

答案 13 :(得分:1)

对我来说,在WCF服务的app.config中的基地址中出现此问题: 当我用过:

<baseAddresses><add baseAddress="http://127.0.0.1:9022/Service/GatewayService"/> </baseAddresses>

如果使用.net连接公共IP或域名就可以了。

但是当使用PHP的SoapClient连接到“http://[online ip]:9022/Service/GatewayService”时,它会抛出异常“Coulod无法连接到主机”

我已将baseAddress更改为[online ip]:9022,一切正常。

答案 14 :(得分:1)

在我看来,wsdl中的服务地址是错误的。

我的wldl网址是。

https://myweb.com:4460/xxx_webservices/services/ABC.ABC?wsdl

但是xml结果中的服务地址是。

<soap:address location="http://myweb.com:8080/xxx_webservices/services/ABC.ABC/"/>

我只是将xml保存到本地文件并将服务地址更改为。

<soap:address location="https://myweb.com:4460/xxx_webservices/services/ABC.ABC/"/>
祝你好运。

答案 15 :(得分:1)

如果ujava的解决方案无法帮助你,你可以尝试使用try / catch来捕获这个致命错误,这对我来说很好。

try{
    $res = $client->__call('LineStopQueryJson',array('Parameters' => $params));
}catch(SoapFault $e){
    print_r($client);
}

答案 16 :(得分:1)

如果服务器上有防火墙,请确保打开SOAP使用的端口。

就我而言,我必须打开1664端口。

iptables -t filter -A INPUT -p tcp --dport 1664 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 1664 -j ACCEPT

答案 17 :(得分:1)

对我来说这是一个DNS问题。我的VPS的名字服务器已经废弃了,所以我通过编辑我的/etc/resolv.conf来切换到谷歌: nameserver 8.8.8.8 nameserver 8.8.4.4

答案 18 :(得分:0)

为了帮助遇到此错误的其他人,<soap:address location="https://some.url"/>中的网址证书无效并导致错误。

答案 19 :(得分:0)

在我的情况下,主机需要TLS 1.2,因此需要使用crypto_method ssl参数强制实施。

$client = new SoapClient($wsdl,
    array(
           'location' => $location,
           'keep_alive' => false,
           "stream_context" => stream_context_create([
                'ssl' => [
                    'crypto_method' =>  STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
                ]
            ]),
           'trace' => 1, // used for debug
        )
    );

答案 20 :(得分:0)

对我来说,这是证书问题。以下为我工作

$context = stream_context_create([
    'ssl' => [
        // set some SSL/TLS specific options
        'verify_peer' => false,
        'verify_peer_name' => false,
        'allow_self_signed' => true
    ]
]);

$client  = new SoapClient(null, [
    'location' => 'https://...',
    'uri' => '...', 
    'stream_context' => $context
]);

答案 21 :(得分:0)

就我而言,禁用的SELINUX允许PHP调用我的WebService。 我在Apache2的FPM中运行PHP

SELinux状态:

# sestatus

禁用SELinux:

setenforce 0

启用SELinux:

# setenforce 1

永久禁用:

edit this file /etc/selinux/config

答案 22 :(得分:0)

如果通过SSL连接,则可能是服务器而非客户端的问题(这是我的情况)。

在大于5.6和7的PHP版本中,检查服务器证书中使用的CipherSuite非常重要。 此版本允许一个完整的密码列表,而这个Web链接中没有一个完整的密码列表:https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Ciphersuite

如果不允许使用所使用的密码(这是不建议使用的算法),则SoapClient会收到“无法连接到主机”的信息,并且不再有任何跟踪信息。

例如,可以通过SoapUI之类的客户端在“ SSL信息”部分中检查所使用的密码。

互联网上没有线程论坛对此进行处理。

也请检查一下:http://php.net/manual/en/migration56.openssl.php

答案 23 :(得分:0)

对我来说,这是httpd服务(Fedora 24)中的一个问题。一个简单的重启就行了:

sudo service httpd restart

答案 24 :(得分:0)

我的php.ini配置错误。验证路径和证书有效性......

[openssl]
openssl.cafile = "C:/good/phpath/ca-bundle.crt"

因为我的新\ SoapClient($ wsdl)是https!

答案 25 :(得分:-1)

版本检查有助于我使用OpenSSL。 OpenSSL_1_0_1f不支持TSLv.1_2! 在github openssl/openssl上检查版本和与TSLv.1_2的兼容性 。并使用新的openssl重新生成您的证书

openssl pkcs12 -in path.p12 -out newfile.pem

P.S我不知道它们是多少,但是这种解决方案确实有帮助。

答案 26 :(得分:-7)

这很可能是指连接问题。可能是您的互联网连接中断,或者您尝试使用的网络服务已关闭。我建议使用此服务查看网络服务是否在线:http://downforeveryoneorjustme.com/