2013-05-03 82 views
3

不斷髮送一些數據點(每秒一次),在PHP中使用無限循環的POST請求。數據非常依賴於時間。如果發生超時,我不關心丟失的數據,我只想快速轉到下一個數據點。fsockopen()超時有時不起作用

我最初使用file_get_contents()(超時值爲1)來做這個POST請求,但我有一些問題,它應該已超時,而不是。我讀了很多關於這個的問題,普遍的共識是,file_get_contents()超時沒有被觸發,因爲它是一個讀取超時,而不是一個連接超時。

我也讀過,套接字有兩種超時,所以我改變了代碼使用fsockopen()來代替。一個片段包含在下面。

// waaaay up at the top of the file 
    ini_set("default_socket_timeout", 1); // set default socket connect timeout 
    //... 
    // inside the loop 
    echo("4..."); 
    $url = 'othersite.ie'; 
    $fp = fsockopen($url, 80, $errno, $errstr, 1); // connect timeout of 1 
    if(!$fp) 
    { 
     echo($errno .": ". $errstr); 
    } 
    else 
    { 
     echo("5..."); 
     stream_set_timeout($fp, 1, 0); // read timeout of 1 

     $content = http_build_query($data); // array assembled before this snippet    
     fwrite($fp, "POST /some/address/at/url HTTP/1.1\r\n"); 
     fwrite($fp, "Host: www.examplesite.ie\r\n"); 
     fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n"); 
     fwrite($fp, "Content-Length: ".strlen($content)."\r\n"); 
     fwrite($fp, "Connection: close\r\n"); 
     fwrite($fp, "\r\n"); 

     fwrite($fp, $content); 

     while(!feof($fp)) 
     { 
      $result = $result . fgets($fp, 1024); 
     } 
     echo("6..."); 

     if (empty($result)) 
     { 
      echo("No result"); 
     } 
    } 

這似乎並沒有幫助,雖然。我添加了一些echo陳述,所以如果我正在觀看輸出結果,我可以看到延遲發生的位置,它總是在「4 ...」和「5 ...」之間。每個延遲大約十秒鐘,而且他們似乎沒有任何特定的順序。大部分時間(超過99%)連接起作用,讀取起作用,並且我將數據發送到服務器。但重要的是至少要試圖消除這些10秒鐘的掛起。任何幫助讚賞。

回答

3

我終於在這方面取得了一些進展。我從來沒有發現錯誤,但懷疑它可能只是在設備的過載硬件上阻塞。爲了解決這個問題,我創建了一個PHP文件來執行一次迭代,並在其上放置了一秒的時間限制。然後我有另一個無限循環的文件,並不斷請求第一個文件。理想情況下,如果迭代文件花費太長時間,請求會失敗,並且循環繼續,這足夠接近我想要的。這有點哈克,但它似乎消除了這個問題。一個非常普遍的例子如下。

迭代:

<?php 

    set_time_limit(1); 
    // fsockopen() etc. 
?> 

循環:

<?php 
    $i = 0; 
    for($i = 0; ; $i++) 
    { 
     file_get_contents("localhost/iteration_file.php"); 
    } 
?> 

也許這將幫助別人。最終,我不得不切換到cURL,但這種方法在很長一段時間內很有用,而且非常可靠。

注意:這個答案反映了我的實際情況,並且不是聲稱要實現最佳做法。我不知道很多最佳實踐。您也可以使用include指令來包含另一個文件,或將功能分解爲方法。

幾個月後編輯:我打算把這個標記爲答案,因爲它在很大程度上解決了我當時的問題。