Исключение SoapFault: Не удалось подключиться к хосту
Иногда не удается вызвать веб-службу.
Эта проблема возникает постоянно.
В чем может быть проблема?
Error:
SoapFault exception: [HTTP] Could not connect to host in
0 [internal function]: SoapClient->__doRequest('<?xml version="...', http://.', '', 1, 0)
21 answers
Проблема была решена.Проблема заключается в кэше
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);
Я добавляю свой комментарий для полноты, так как перечисленные здесь решения мне не помогли. На PHP 5.6 SoapClient выполняет первый вызов указанного URL-адреса WSDL в SoapClient::SoapClient
и после подключения к нему и получения результата пытается подключиться к WSDL, указанному в результате в:
<soap:address location="http://"/>
И вызов завершается ошибкой Could not connect to host
, если WSDL отличается от указанного вами в SoapClient::SoapClient
и недоступен (в моем случае был SoapUI с использованием http://host.local/).
В поведение в PHP 5.4 отличается, и он всегда использует WSDL в SoapClient::SoapClient
.
Хост либо не работает, либо очень медленно реагирует. Если он реагирует медленно, вы можете попробовать увеличить время ожидания с помощью опции 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
Вы также можете включить обработку ошибок, как указал занлок, чтобы повторить попытку несколько раз. Если у вас есть пользователи на самом деле, ожидая этих вызовов SOAP, вы захотите поставить их в очередь, обработать в фоновом режиме и уведомить пользователя, когда они будут завершены.
В вашем файле 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, это может вызвать эту проблему при изменении URI wsdl в php-коде.
в этом примере вы можете просто удалить файл, начинающийся с wsdl-
в каталоге /tmp
.
или вы просто устанавливаете soap.wsdl_cache_enabled=0;
и soap.wsdl_cache_ttl=0;
PHP будет извлекать файл wsdl каждый раз, когда вы посещаете страницу.
Я сам столкнулся с этой проблемой и после долгих поисков в конце концов нашел эту ошибку для ubuntu:
Https://bugs .launchpad.net/ubuntu /+источник/openssl/+ошибка/965371
В частности
Https://bugs .launchpad.net/ubuntu /+источник/openssl/+ошибка/965371/комментарии/62
openssl s_client -connect site.tld:443
однако неудача openssl s_client -tls1 -connect site.tld:443
дала успех. В моем конкретном случае часть выходных данных включала
New, TLSv1/SSLv3, Cipher is RC4-MD5
поэтому я соответствующим образом установил значение ssl/шифра контекста php.
Похоже, что ошибка SoapFault exception: Could not connect to host
может быть вызвана несколькими разными причинами. В моем случае это не было вызвано прокси, брандмауэром или DNS (на самом деле у меня было соединение SOAP с той же машины, работающей с использованием nusoap без какой-либо специальной настройки).
Наконец, я обнаружил, что это было вызвано недопустимым файлом pem
, на который я ссылался в опции local_cert
в моем конструкторе SoapClient.
Решение:
Когда я удалил цепочку сертификатов из файла pem
, так что только содержал сертификат и закрытый ключ, начали проходить вызовы SOAP.
В нашем случае это была проблема согласования шифров. Мы получали эту ошибку случайным образом. Мы решили нашу проблему, используя шифры, подобные этому:
$soapClient = new SoapClient('http://example.com/soap.asmx?wsdl',array("stream_context" => stream_context_create(array('ssl' => array('ciphers'=>'AES256-SHA')))));
Похоже, что PHP не согласовывал одни и те же шифры при каждом вызове службы.
Для меня это была проблема DNS. Серверы имен моего VPS вышли из строя, поэтому я переключился на Google, отредактировав свой /etc/resolv.conf следующим образом: сервер имен 8.8.8.8 сервер имен 8.8.4.4
Если на вашем сервере установлен брандмауэр, обязательно откройте порт, используемый SOAP.
В моем случае мне пришлось открыть порт 1664.
iptables -t filter -A INPUT -p tcp --dport 1664 -j ACCEPT
iptables -t filter -A OUTPUT -p tcp --dport 1664 -j ACCEPT
Если решение уджавы не может вам помочь, вы можете попробовать использовать try/catch, чтобы поймать это смертельное, это отлично работает на мне.
try{
$res = $client->__call('LineStopQueryJson',array('Parameters' => $params));
}catch(SoapFault $e){
print_r($client);
}
Со мной эта проблема в базовом адресе в app.config службы WCF: Когда я использовал:
<baseAddresses><add baseAddress="http://127.0.0.1:9022/Service/GatewayService"/> </baseAddresses>
Это нормально, если вы используете .net для подключения к общедоступному ip-адресу или домену.
Но когда вы используете SoapClient PHP для подключения к "http://[online ip]:9022/Service/GatewayService
", возникает исключение "Не может подключиться к хосту"
Я изменил базовый адрес на [сетевой ip]: 9022, и все в порядке.
В моем случае это сработало после подключения к wsdl, используйте функцию __setLocation()
, чтобы снова определить местоположение, потому что вызов завершается ошибкой:
Не удалось подключиться к хосту
Это происходит, если WSDL отличается от указанного в SoapClient::SoapClient
.
Я, наконец, нашел причину, по которой библиотека не может найти пакет CA в вашей системе. PHP>=v5.6 автоматически устанавливает verify_peer в значение true по умолчанию. Однако не все системы имеют известный пакет CA на диске.
Вы можете попробовать одну из следующих процедур:
1. Если в вашей системе есть файл CA, укажите openssl.cafile
или curl.cainfo
в php.ini
путь к файлу CA.
2. Вручную укажите местоположение файла SSL CA
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($cHandler, CURLOPT_CAINFO, $path-of-your-ca-file);
3. отключен проверить_пир
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
В моем случае адрес службы в wsdl неверен.
Мой URL-адрес wsdl.
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/"/>
Удачи.
У меня была плохая конфигурация php.ini. Проверьте путь и действительность сертификата...
[openssl]
openssl.cafile = "C:/good/phpath/ca-bundle.crt"
Потому что мой новый \SoapClient($wsdl) был https!
Просто чтобы помочь другим людям, которые столкнулись с этой ошибкой, URL-адрес в <soap:address location="https://some.url"/>
имел недействительный сертификат и вызвал ошибку.
Для меня это была проблема в сервисе httpd
(Fedora 24). Простой перезапуск сделал свое дело:
sudo service httpd restart
Неправильно сконфигурированная служба оставляет пространство имен по умолчанию с tempuri.org
Это означает, что соединение с wsdl будет работать, но вызов функции завершится ошибкой.
Трассировка стека:
SoapClient->__Дореквест('http://example.com ...', 'http://tempuri.org....', 2, 0)
Чтобы исправить это, вы должны явно указать местоположение с помощью __setLocation()
$this->soapClient = new \SoapClient(WS_URL);
$this->soapClient->__setLocation(WS_URL);
Эта работа для меня
$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)
));
Если соединение осуществляется через SSL, это может быть проблемой сервера, а не клиента (это мой случай).
В версиях PHP выше 5.6 и 7 важно проверить набор шифров, используемый в сертификате сервера. Существует полный список шифров, разрешенных этой версией, и полный список шифров, которых нет в этой веб-ссылке: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Ciphersuite
Если используемый шифр не разрешен (он устарел алгоритм), SoapClient получает сообщение "Не удалось подключиться к хосту", и больше никаких следов об этом нет.
Используемый шифр может быть проверен такими клиентами, как SoapUI, например, в разделе "Информация о SSL".
В Интернете нет форума, посвященного этому вопросу.
Проверьте и это тоже: http://php.net/manual/en/migration56.openssl.php
Это, скорее всего, относится к проблеме с подключением. Это может быть либо то, что ваше интернет-соединение было отключено, либо веб-служба, которую вы пытаетесь использовать, была отключена. Я предлагаю использовать эту услугу, чтобы узнать, подключена ли веб-служба к сети или нет: http://downforeveryoneorjustme.com/