2013-07-19 3 views
2

Я уже некоторое время изучаю и экспериментирую с этой проблемой и еще не нашел работоспособного решения, поэтому я думаю, что пришло время обратиться за помощью.исправление зависания curl_exec в Windows 8 apache

У меня проблема с curl_exec, но только на определенном сервере. Вот некоторые фон, первый:

  • Процессор: Intel Core I7
  • Оперативная память: 64GB
  • ОС: Windows 8.0
  • Сервер: Apache 2.4.4 x86 TS
  • PHP версия: 5.5.1 x86 TS ж/Xdebug 2.2.3
  • Curl версия: 7.30.0

PHP код, который демонстрирует проблему:

$input_vars = (!empty($_POST)) ? filter_input_array(INPUT_POST) : array(); 
$url = 'http://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php'; 
$qs = '?'; 
foreach ($input_vars as $key => $value) 
{ 
    $qs .= "$key=$value&"; 
} 
$qs= rtrim($qs, '&'); 
$url .= $qs; 
$bot_id = $input_vars['bot_id']; 
$options = array(
    CURLOPT_USERAGENT => 'Program O XML API', 
    CURLOPT_RETURNTRANSFER => true, 
    //CURLOPT_POST => 1, 
    CURLOPT_MAXREDIRS => 5, 
    CURLOPT_CONNECTTIMEOUT => 5, 
    CURLOPT_TIMEOUT => 5, 
); 
$ch = curl_init($url); 
curl_setopt_array($ch, $options); 
//curl_setopt($ch, CURLOPT_POSTFIELDS, $input_vars); 
$data = curl_exec($ch); 
$debug = curl_getinfo($ch); 
curl_close($ch); 
echo '<pre>Data = ', htmlentities($data), '</pre><br>'; 
var_dump($debug); 

Как можно видеть, я пытался это как с GET и POST, и оба дают те же результаты. Параметры тайм-аута, перечисленные выше, существуют, чтобы сценарий не запускался неопределенно. У меня было это зависание более 3 часов, прежде чем я остановлю службу Apache, чтобы остановить зависание (просто отмена в браузере этого не сделает). Выход из сценария выглядит следующим образом:

array (size=26) 
    'url' => string 'ht tp://192.168.1.100/geekcavecreations/Morti/chatbot/conversation_start.php?say=hello&bot_id=1&convo_id=78a9s39gut34lurq055in5s6r4&format=xml' (length=141) 
    'content_type' => null 
    'http_code' => int 0 
    'header_size' => int 0 
    'request_size' => int 203 
    'filetime' => int -1 
    'ssl_verify_result' => int 0 
    'redirect_count' => int 0 
    'total_time' => float 5 
    'namelookup_time' => float 0 
    'connect_time' => float 0 
    'pretransfer_time' => float 0 
    'size_upload' => float 0 
    'size_download' => float 0 
    'speed_download' => float 0 
    'speed_upload' => float 0 
    'download_content_length' => float -1 
    'upload_content_length' => float 0 
    'starttransfer_time' => float 0 
    'redirect_time' => float 0 
    'redirect_url' => string '' (length=0) 
    'primary_ip' => string '192.168.1.100' (length=13) 
    'certinfo' => 
    array (size=0) 
     empty 
    'primary_port' => int 80 
    'local_ip' => string '192.168.1.100' (length=13) 
    'local_port' => int 2546 

Data = 

(не мог понять, лучший способ форматирования, что, извините)

Кроме того, на этом же компьютере несколько виртуальных машин, каждая из которых различные версии OS/Server/PHP и все с точно таким же корнем физического документа, который находится на главной машине. Эти машины варьируются от Windows 7/IIS до CentOS/Apache 2.2 и других комбинаций, и все они без исключения запускают этот же скрипт без проблем и выводят ожидаемый XML-документ. Если я бегу URL в только веб-браузер, выход следующим образом:

<?xml version="1.0"?> 
<program_o> 
    <version>2.3.0</version> 
    <status><success>1</success></status> 
    <bot_id>1</bot_id> 
    <bot_name>Morti</bot_name> 
    <user_id>1</user_id> 
    <user_name>Seeker</user_name> 
    <chat> 
    <line> 
     <input>hello</input> 
     <response>And a good failed to you, undefined. How are you?</response> 
    </line> 
    </chat> 
</program_o> 

Я также взял выше вывод XML и сохраняется в файл, и был сценарий проблемы выполните cURL вызывает URL-адрес для этого сохраненного XML-файла, и скрипт работает без проблем в этот момент, поэтому я также создал макет-скрипт, который создает только объект SimpleXMLElement, заполняет несколько новых тегов, а затем echo - asXML () выводится из созданного объекта (в основном, что делает chat_start.php, но гораздо менее сложным), и я получаю ту же проблему. Код для макетной скрипта ниже:

$xml = new SimpleXMLElement('<program_o></program_o>'); 
$xml->addChild('version', '2.3.0'); 
$status = $xml->addChild('status'); 
$status->addChild('success', '1'); 
$xml->addChild('bot_id', '1'); 
$xml->addChild('bot_name', 'Morti'); 
$xml->addChild('user_id', '1'); 
$xml->addChild('user_name', 'Seeker'); 
$chat = $xml->addChild('chat'); 
$line = $chat->addChild('line'); 
$line->addChild('input', 'hello'); 
$line->addChild('response', 'And a good failed to you, undefined. How are you?'); 
$output = $xml->asXML(); 
header('Content-type: text/xml'); 
exit($output); 

Я довольно много на моем конце остроумия здесь. Я изменил версии PHP, версии Apache, пробовал бесчисленные предложения, которые я нашел здесь на SO, для других проблем с замораживанием cURL, как найдено here, here и here, среди двойных дюжин или нескольких других.

И теперь, когда я написал книгу, чтобы представить свою проблему, я должен спросить: как я могу получить cURL, чтобы не повеситься на платформе Windows 8?

ответ

1

Ну, похоже, я, наконец, попал в корень проблемы.Похоже, что когда вы выполняете вызов cURL на тот же сервер, что и скрипт, выполняющий вызов, и, если оба сценария «вызывающий» и «вызываемый» пытаются использовать один и тот же идентификатор сеанса, возникает взаимоблокировка, заставляя оба сценария ждать, пока другой не освободит сеанс. Я закончил тем, что добавил тест, чтобы увидеть, есть ли уже используемый идентификатор сеанса, и если это так, вызывающий скрипт не запускает сеанс. Если идентификатор сеанса отсутствует, то вызывающий абонент запускает сеанс, получает идентификатор сеанса, а затем уничтожает сеанс, который позволяет сценарию «вызываемого» неограниченного доступа к указанному сеансу, тем самым устраняя ситуацию взаимоблокировки. Ниже приведен код, который я использовал для этого:

$convo_id = (isset ($request_vars['convo_id'])) ? $request_vars['convo_id'] : get_convo_id(); 
// do stuff here 
function get_convo_id() 
{ 
    session_name('Program O XML GUI'); 
    session_start(); 
    $convo_id = session_id(); 
    session_destroy(); 
    return $convo_id; 
} 

Используя этот метод, все работает, как ожидалось. Я искренне надеюсь, что это окажется полезным для других в будущем.