Исключение SoapFault: Не удалось подключиться к хосту - программирование
Подтвердить что ты не робот

Исключение SoapFault: Не удалось подключиться к хосту

Иногда не удается вызвать веб-службу.

Эта проблема происходит все время.

В чем может быть проблема?

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

Ответ 1

Проблема решена. Проблема заключается в кеше

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

Ответ 2

Я добавляю свой комментарий для полноты, поскольку перечисленные здесь решения не помогли мне. На 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.

Ответ 3

Хост либо работает, либо очень медленно реагирует. Если он медленно реагирует, вы можете попытаться увеличить время ожидания с помощью параметра 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-вызовов, вам нужно будет поставить их в очередь и обработать их в фоновом режиме и уведомить пользователя, когда они будут завершены.

Ответ 4

в файле php.ini, который управляет кэшем доступа wsdl, есть раздел конфигурации soap, может отображаться как:

[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 каждый раз, когда вы посещаете страницу.

Ответ 5

неправильно настроенный сервис оставляет пространство имен по умолчанию с tempuri.org

Это означает, что соединение с wsdl будет работать, но вызов функции не удастся.

Stacktrace:

SoapClient->__doRequest('http://example.com...', 'http://tempuri.org....', 2, 0)

Чтобы исправить это, вы должны явно указать местоположение, используя __setLocation()

$this->soapClient = new \SoapClient(WS_URL);
$this->soapClient->__setLocation(WS_URL);

Ответ 6

Я сам попал в эту проблему, и после долгого рытья я в конце концов нашел эту ошибку для ubuntu:

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, поэтому я правильно установил значение ssl/cipher для php-контекста.

Ответ 7

В нашем случае это была проблема переговоров с шифрами. Мы получили эту ошибку случайно. Мы решили нашу проблему с помощью шифра следующим образом:

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

Похоже, PHP не согласовывал одни и те же шифры при каждом вызове службы.

Ответ 8

В моем случае он работал после подключения к wsdl, используйте функцию __setLocation(), чтобы определить местоположение снова, потому что вызов завершился с ошибкой:

Не удалось подключиться к хосту

Это происходит, если WSDL отличается от указанного в SoapClient::SoapClient.

Ответ 9

Кажется, что ошибка SoapFault exception: Could not connect to host может быть вызвана несколькими разными вещами. В моем случае это не было вызвано прокси-сервером, брандмауэром или DNS (у меня на самом деле было соединение SOAP с той же машины, что и с помощью nusoap без любая специальная настройка).

Наконец, я обнаружил, что это было вызвано недопустимым pem файлом, на который я ссылался в опции local_cert в моем конструкторе SoapClient.

Решение: Когда я удалил цепочку сертификатов из файла pem, поэтому только содержал сертификат и закрытый ключ, вызовы SOAP начали проходить.

Ответ 10

Это работа для меня

$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)
  ));

Ответ 11

Наконец-то я нашел причину, потому что ее библиотека не может найти набор СА в вашей системе. PHP >= v5.6 автоматически устанавливает verify_peer в true по умолчанию. Однако не все системы имеют известный набор СА на диске.

Вы можете попробовать одну из следующих процедур:

1.Если у вас есть файл CA в вашей системе, установите openssl.cafile или curl.cainfo в свой php.ini путь к вашему файлу CA.

2.Установите свое местоположение файла CA 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);

Ответ 12

Для меня это проблема DNS. Мои серверы имен VPS исчезли, поэтому я переключился на Google, отредактировав файл /etc/resolv.conf следующим образом: сервер имен 8.8.8.8 nameserver 8.8.4.4

Ответ 13

Если у вас есть брандмауэр на вашем сервере, обязательно откройте порт, используемый SOAP.

В моем случае мне пришлось открыть порт 1664.

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

Ответ 14

Если решение ujava не может вам помочь, вы можете попробовать использовать try/catch, чтобы поймать этот фатальный, это отлично работает на меня.

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

Ответ 15

В моем случае служебный адрес в wsdl неверен.

Мой wsdl url.

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/"/>

Удачи.

Ответ 16

Со мной эта проблема в базовом адресе в app.config службы WCF: Когда я использовал:

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

это нормально, если вы используете .net для подключения к общедоступному ip или домену.

Но когда вы используете PHP SoapClient для подключения к "http://[online ip]:9022/Service/GatewayService", он генерирует исключение "Coulod not connect to host"

Я изменил baseAddress на [онлайн-ip]: 9022 и все нормально.

Ответ 17

Для тех, кто так же, как и я, боролся с консольной командой laravel artisan, которая делает много запросов к одному и тому же wsdl внешнего мыльного сервера, а затем через некоторое время завершается с ошибкой Could not connect to host error.

Проблема была в том, что я создавал новый экземпляр SoapClient каждый раз перед тем, как был сделан запрос. Не делай этого. Создайте его один раз и сделайте каждый запрос от одного и того же клиента.

Надеюсь, поможет.

Ответ 18

У меня была плохая конфигурация php.ini. Проверьте путь и срок действия сертификата...

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

Поскольку мой новый \SoapClient ($ wsdl) был https!

Ответ 19

Чтобы помочь другим людям, столкнувшимся с этой ошибкой, URL-адрес в <soap:address location="https://some.url"/> имел недопустимый сертификат и вызвал ошибку.

Ответ 20

Для меня это проблема в службе httpd (Fedora 24). Простой перезапуск сделал трюк:

sudo service httpd restart

Ответ 21

Если соединение через SSL, может быть проблема сервера, а не клиента (это мой случай).

В версиях PHP выше 5.6 и 7 важно проверить CipherSuite, используемый в сертификате сервера. Существует полный список шифров, разрешенных этими версиями, и полный список шифров, которых нет в данной веб-ссылке: https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Ciphersuite.

Если используемый шифр недопустим (это устаревший алгоритм), SoapClient получает сообщение "Не удалось подключиться к хосту", и в нем больше нет следов.

Используемый шифр может быть проверен такими клиентами, как SoapUI, например, в разделе "Информация SSL".

В интернете нет ветки, посвященной этой теме.

Проверьте это тоже: http://php.net/manual/en/migration56.openssl.php

Ответ 22

Для меня это была проблема с сертификатом. Следующее сработало у меня

$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
]);

Ответ 23

Проверка версии помогла мне OpenSSL. OpenSSL_1_0_1f не поддерживается TSLv.1_2! Проверьте версию и совместимость с TSLv.1_2 на github openssl/openssl , И восстановите свой сертификат с новым openssl

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

P.S. Я не знаю, в чем они были минус, но это решение действительно поможет.

Ответ 24

Это скорее всего относится к проблеме подключения. Это может быть либо то, что ваше интернет-соединение было недоступно, либо веб-сервис, который вы пытаетесь использовать, был недоступен. Я предлагаю использовать эту услугу, чтобы узнать, находится ли веб-служба в сети или нет: http://downforeveryoneorjustme.com/