2017-05-08 17 views
1

私は下のPHPの関数でタイムアウトを設定しようとしていますが、ページの読み込みを避けるために、私はtcpメッセージをipとポート経由でPHP経由で送る必要があります。 ipとportに到達できませんか?PHPのソケットタイムアウト設定が機能していませんか?

私は以下のsocket_set_optionメソッドを使用しようとしましたが、残念ながら最大30秒かかることがあります。

は私がlaravel

public static function send($command, $data = '') 
{ 
    $MUSdata = $command . chr(1) . $data; 
    $socket = \socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp')); 

    $connect_timeval = array(
     "sec"=>0, 
     "usec" => 100 
    ); 

    \socket_set_option(
     $socket, 
     SOL_SOCKET, 
     SO_SNDTIMEO, 
     $connect_timeval 
    ); 

    \socket_connect($socket, Config::get('frontend.client_host_ip'), Config::get('frontend.mus_host_port')); 
    \socket_send($socket, $MUSdata, strlen($MUSdata), MSG_DONTROUTE);  
    \socket_close($socket); 
} 
+1

残念ながら、 'SO_SNDTIMEO'は、接続タイムアウトには影響を与えません。ソケットが接続された後の書き込み操作のみ。ソケットをノンブロッキングモードにし、connect(ソケットが接続されるまでEAGAINを返す)の独自のタイムアウトループを作成し、ソケットをブロックモードに戻す必要があります。私はこれを答えとして掲示したいと思いますが、PHPがそれをサポートしているのであれば、わかりません。 –

答えて

0

残念ながら5.2プロジェクトでこれを使用し、SO_SNDTIMEOは、接続タイムアウトには影響を与えません。ソケットが接続された後の書き込み操作のみ。ソケットをノンブロッキングモードにし、connect(ソケットが接続されるまでEAGAINを返す)の独自のタイムアウトループを作成し、ソケットをブロックモードに戻す必要があります。

@Lotharyxのコメントに基づいて、私は小さなconnect_with_timeout関数を書いています。
この関数は、ソケットが時間内に接続する場合はtrueを返し、そうでない場合はfalseを返します。 $timeoutは秒単位のタイムアウトで、$con_per_secは1秒あたりの接続試行回数です。 WindowsとLinuxでテスト
、PHPの5.5.x

function connect_with_timeout($soc, $host, $port, $timeout = 10) { 
    $con_per_sec = 100; 
    socket_set_nonblock($soc); 
    for($i=0; $i<($timeout * $con_per_sec); $i++) { 
     @socket_connect($soc, $host, $port); 
     if(socket_last_error($soc) == SOCKET_EISCONN) { 
      break; 
     } 
     usleep(1000000/$con_per_sec); 
    } 
    socket_set_block($soc); 
    return socket_last_error($soc) == SOCKET_EISCONN; 
} 
関連する問題