PHP5 SoapClient - 无法连接到主机,具体取决于客户端环境

时间:2017-10-30 23:39:21

标签: php web-services soap

一位朋友正在使用PHP 5.x开发第三方soap客户端。客户端已经完成,并且在连接到dev端点的服务器(Debian + Apache)上正常工作。现在他想要更改为生产端点和认证,但总是得到"无法连接到主机"错误消息没有任何解释。具有相同证书的相同代码适用于localhost,甚至可以使用导入的证书从Firefox运行。只有服务器的SoapClient不想连接它。根据他的说法,错误几乎是即时的,所以它不是某种超时。他试图从服务器telnet端点并且已连接,因此它不是防火墙问题。他已经邮寄给webservice维护者来获取日志,但还没有回复。知道什么可以导致SOAP导致这样的环境依赖问题吗?

这是代码,但我想它不包含任何解决此问题的信息:

$soapLocation = (DEV_ENV ? 'https://dev.example.com:443' : 'https://prod.example.com:443').$soapLocationUri;  
$soapClient = new SoapClient(  
        './wsdl/'.$wsdlFileName,  
        array(  
                'local_cert'                    => (DEV_ENV ? './cert/***.pem' : './cert/***.pem'),  
                'passphrase'                    => (DEV_ENV ? 'xxx' : 'xxx'),  
                'location'                      => $soapLocation,  
                'trace'                             => true,  
                'exceptions'                    => true,  
                'keep_alive'                    => true,  
                'connection_timeout'    => 10,  
                'cache_wsdl'                    => WSDL_CACHE_NONE,  
                'soap_version'              => SOAP_1_1,  
                'stream_context'            => stream_context_create(array(  
                        'ssl'   => array(  
                                'verify_peer'               => false,  
                                'verify_peer_name'  => false,  
                                'allow_self_signed' => true  
                        )  
                ))  
        )  
); 

和例外:

object(SoapFault)#2 (9) {  
  ["message":protected]=>  
  string(25) "Could not connect to host"  
  ["code":protected]=>  
  int(0)  
  ["trace":"Exception":private]=>  
  array(2) {  
    [0]=>  
    array(6) {  
      ["function"]=>  
      string(11) "__doRequest"  
      ["class"]=>  
      string(10) "SoapClient"  
      ["args"]=>  
      array(4) {  
        [0]=>  
        string(1188) "...xml..."  
        [1]=>  
        string(53) "https://prod.example.com:443/BLAH/BLAH_NO_SAML"  
        [2]=>  
        string(0) ""  
        [3]=>  
        int(1)  
      }  
    }  
    ...  
  }  
  ["previous":"Exception":private]=>  
  NULL  
  ["faultstring"]=>  
  string(25) "Could not connect to host"  
  ["faultcode"]=>  
  string(4) "HTTP"  
} 

1 个答案:

答案 0 :(得分:0)

根据webservice维护者的说法,生产环境强制执行TLSv1.2,而dev环境允许TLSv1.0。我们用

进行了测试
C3:D29

它失败了,所以这就是原因。

PHP SoapClient使调试连接错误变得非常困难。有些人建议SoapUI在开发客户端之前测试webservices。我同意这一部分,但如果您使用bug from 2004仍然存在的扩展名,那么我认为问题不在于扩展名,而在于您选择的工具。

只是写一些关于如何在没有相关错误消息的情况下调试此类错误的相关内容。如果您有一个可行的解决方案,那么总有一种方法可以调试。我在实验课程设计中学到了这种方法,它们可能是由Taguchi开发的(不确定那部分)。首先,您需要列出产品的各个部分。在目前的情况下:webservice,网络,硬件,操作系统,防火墙,网络服务器,语言,代码。您需要使用工作产品并逐个更换,直到故障部件出现错误为止。所以我们的工作产品在不同的机器上,但具有相同的网络,因此我们可以排除Web服务和网络。首先我们需要更换硬件,因此我们需要制作vm或docker镜像,然后先在我们的笔记本电脑和服务器上再试一次。如果它工作,那么opsystem是下一个。我们需要将工作解决方案移动到相同的操作系统。有时这并不容易,但我们可以管理它,例如我们可以在笔记本电脑上测试后使用nginx而不是apache(拥有不同的网络服务器)。如果它在服务器上不起作用,那么操作系统设置或防火墙设置是错误的。如果它有效,那么我们需要尝试使用相同的Web服务器。我们可以为我们不同的php版本使用不同的扩展名,或者如果它在笔记本电脑上运行,我们可以使用完全不同的语言。之后代码将是下一个,但在这种情况下它是相同的。使用这种方法我们会得到语言失败(如果libcurl附带),所以我们将知道某些扩展或一些php.ini设置或php版本在这种情况下是错误的。另外3个部分要检查...