Я пытаюсь обработать поток, который отправляет мне дискретные пакеты информации, но имеет неизвестную продолжительность времени между пакетами - скажем, порядка 1-10 секунд. Я хочу загрузить поток с помощью PHP-скрипта, но также сохранить все данные, которые у меня есть до сих пор, в мою локальную базу данных каждые 5 секунд, передает ли поток мои данные или нет. Некоторые 5-секундные интервальные записи будут пустыми; такое поведение ожидается и желательно, если это произойдет с данными.
У меня есть код вроде:
$fp = fopen($stream_url, 'r');
while (!feof($fp)) {
// Download stream
$stream_data .= fread($fp, 128);
// Process $stream_data
[...]
// Check time and save data
if ($time_since_last_insert == 5) {
// Save to database
[...]
// Reset vars to be ready for new data in the next loop iteration
$stream_data = '';
}
}
Согласно документам, которые я прочитал, fread() ожидает, пока он не прочитает указанное количество байтов, прежде чем возвращать что-либо в $ stream_data. Но мне нужно, чтобы он "отпустил", если в настоящее время нет байтов для чтения (т.е. Stream_get_meta_data() говорит "unread_bytes" == 0) и разрешает код ниже проверять время и вносить вставки БД по мере необходимости.
TL; DR, мне нужно запустить два процесса одновременно:
Можно ли проверить, сколько байтов осталось в потоке перед запуском fread() и продолжить мой цикл while, если unread_bytes '== 0? Или можно установить какой-то тайм-аут на fread(), не нарушая соединение всего потока? Я открыт для того, чтобы PHP не был правильным языком, чтобы делать то, что я делаю, но это то, что я знаю, поэтому я действительно хотел бы использовать его, если это возможно.
Иногда формулирование вопроса для других - это лучший способ задать вам правильный путь, чтобы найти правильный ответ для себя. Я заметил, что один из элементов массива stream_get_meta_data()
был "blocking" => "true", и поскольку я только что закончил спрашивать о разблокировке fread()
, это заставило меня искать способ установить "блокировку" на " ложный."
Использовать: stream_set_blocking($fp, 0);
, после fopen()
но до цикла
(docs)