2012-05-24 119 views
6

我使用PHP ssh2庫,並簡單地做:PHP ssh2_connect()執行超時

$ssh = ssh2_connect($hostname, $port); 

的問題是我想設置一個超時,即5秒後停止嘗試連接。據我所知,ssh2庫本身不支持連接超時。我怎樣才能實現一個超時包裝?

+0

你有沒有想過如何做到這一點? – solefald

回答

0

libssh2庫本身不執行connect(),所以它不必爲此提供超時。然而,libssh2確實提供超時功能,它確實提供...

2

我一直在同一個問題掙扎了一段時間。 事實是,嘗試連接到一個「死」或無響應的服務器與ssh2將拖延您的應用程序,只要目標服務器的最大連接時間限制。

 

最簡單的辦法事先檢測是否您的實例將會引起SHH-ING到它是平它(看它是否響應),當你煩惱。

function getPing($addr) 
{ 
    //First try a direct ping 
    $exec = exec("ping -c 3 -s 64 -t 64 ".$addr); 
    $array = explode("/", end(explode("=", $exec))); 
    if(isset($pingVal[1])) 
    { 
     //There was a succesful ping response. 
     $pingVal = ceil($array[1]); 
    } 
    else 
    { 
     //A ping could not be sent, maybe the server is blocking them, we'll try a generic request. 
     $pingVal = callTarget($addr); 
    } 


    echo intval($pingVal)."ms"; 
    if($pingVal > ["threshold"]) 
    { 
     return false; 
    } 
    return true; 
} 

function callTarget($target) 
{ 
    $before = microtime(); 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $target); 
    curl_setopt($ch, CURLOPT_NOBODY, true); 
    if (curl_exec($ch)) 
    { 
     curl_close($ch); 
     return (microtime()-$before)*1000; 
    } 
    else 
    { 
     curl_close($ch); 
     return 9999; 
    } 
} 

這種方法可以讓你得到你的服務器的狀態更快的響應,所以你知道,如果你將要浪費你的時間的ssh-ING進去。

+0

我發現簡單的Ping思路非常有用,在拋出我的自定義異常之前保存了30秒的超時時間。謝謝! – Jimbo

1

我知道這是一箇舊線程,但問題仍然存在。所以,這是它的解決方案。

ssh2_connect()使用socket_connect()socket_connect依靠這是默認設置爲60秒(http://php.net/manual/en/filesystem.configuration.php#ini.default-socket-timeout

因此,PHP的ini配置參數default_socket_timeout來解決我們的問題的最簡單的方法是在運行時修改INI設置我們想要的值,並且比背到ini文件中設置的值,所以我們避免影響我們軟件的其他部分。在下面的示例中,新值設置爲2秒。

$originalConnectionTimeout = ini_get('default_socket_timeout'); 
    ini_set('default_socket_timeout', 2); 

    $connection = ssh2_connect('1.1.1.1'); 

    ini_set('default_socket_timeout', $originalConnectionTimeout); 

您可以找到有關SSH2對PHP的工作方式通過閱讀libssh2的源代碼(https://github.com/libssh2/libssh2)的進一步細節。