随着您开始同步stream_set_blocking($resource, true)
读取流,这意味着每次调用都会等待直到有数据要读取。然后调用,它从阻塞流中读取,直到到达 EOF(关闭)。结果是您一个接一个地读取流,而不是“同时”读取。fread()
stream_get_contents()
以这种方式读取流很常见并且最容易编码,但是当您想要同时处理多个流时,您必须自己处理缓冲区、计时和“流结束”检测。使用您当前的代码,这部分通过阻塞流和stream_get_contents()
.
要同时读取多个流,您应该重写代码以异步读取流。
// $streamArray is an array of streams obtained by stream_socket_client("..");
$buffers = array();
$num_streams = 0;
foreach($streamArray as $stream) {
// set streams non-blocking for asynchroneous reading
stream_set_blocking($stream, false);
// write command to all streams - multiplexing
fputs($stream, $command);
// initialize buffers
$buffers[$stream] = '';
$num_streams++;
}
while($num_streams > 0) {
// use stream_select() to wait for new data and not use CPU at 100%.
// note that the stream arrays are passed by reference and are modified
// by stream_select() to reflect which streams are modified / have a
// new event. Because of this we use a copy of the original stream array.
// also note that due to a limitation in ZE you can not pass NULL directly
// for more info: read the manual https://php.net/stream_select
$no_stream = NULL;
$select_read = $streamArray;
stream_select($select_read, $no_stream, $no_stream, null);
// if there is new data, read into the buffer(s)
foreach($select_read as $stream) {
$buffers[$stream] .= fread($stream, 4096);
// check if the stream reached end
if (feof($stream)) {
$key = array_search($stream, $streamArray);
// close stream properly
$num_streams--;
fclose($stream);
// remove stream from array of open streams
unset($streamArray[$key]);
}
}
}
// do something with your buffers - our use them inside the while() loop already
print_r($buffers);