私は stream_select() を使用していますが、数秒後に0個の記述子を返し、まだ読み取るデータがある間に関数を返します。
珍しいことですが、タイムアウトを 0 に設定すると、記述子の数が常にゼロになります。
$num = stream_select($read, $w, $e, 0);
stream_select()関数は基本的に、最初の 3 つの引数で指定したストリーム セレクターをポーリングするだけです。つまり、次のイベントのいずれかが発生するまで待機します。
したがって、戻り値として0 を受け取ることは完全に正常であり、現在のポーリング サイクルで新しいデータがなかったことを意味します。
関数を次のようなループに入れることをお勧めします。
$EOF = false;
do {
$tmp = null;
$ready = stream_select($read, $write, $excl, 0, 50000);
if ($ready === false ) {
// something went wrong!!
break;
} elseif ($ready > 0) {
foreach($read as $r) {
$tmp .= stream_get_contents($r);
if (feof($r)) $EOF = true;
}
if (!empty($tmp)) {
//
// DO SOMETHING WITH DATA
//
continue;
}
} else {
// No data in the current cycle
}
} while(!$EOF);
この例では、スクリプトは入力ストリーム以外のすべてを完全に無視することに注意してください。また、「if」ステートメントの 3 番目のセクションは完全にオプションです。
0
数値またはFALSE
ブール値を返しますか? FALSE
何らかのエラーが発生したことを意味しますが、タイムアウトが原因でゼロになるか、ストリームで興味深いことが何も起こらなかったため、新しい選択などを行う必要があります。
これは、チェックしてすぐに戻るため、タイムアウトがゼロの場合に発生する可能性があると思います。また、 stream-select に関する PHP マニュアルを読むと、ゼロ タイムアウトの使用に関する次の警告が表示されます。
タイムアウト値 0 を使用すると、ストリームのステータスを即座にポーリングできますが、ループでタイムアウト値 0 を使用すると、スクリプトが CPU 時間を消費しすぎるため、お勧めできません。
これが TCP ストリームであり、接続のクローズを確認したい場合は、fread
etc からの戻り値をチェックして、他のピアが接続をクローズしたかどうかを判断する必要があります。read
ストリーム配列引数について:
読み取り配列にリストされたストリームは、文字が読み取り可能になるかどうかを監視します (より正確には、読み取りがブロックされないかどうかを確認します。特に、ストリーム リソースはファイルの終わりでも準備ができています。 fread() は長さゼロの文字列を返します)。
http://www.php.net/stream_select
現在の Zend Engine の制限により、NULL などの定数修飾子を、このパラメーターが参照によって渡されることを期待する関数にパラメーターとして直接渡すことはできません。代わりに、一時変数または左端のメンバーが一時変数である式を使用します。
<?php $e = NULL; stream_select($r, $w, $e, 0); ?>