Разблокируйте fread (), если unread_bytes == 0, без тайм-аута соединения с потоком

1

Я пытаюсь обработать поток, который отправляет мне дискретные пакеты информации, но имеет неизвестную продолжительность времени между пакетами - скажем, порядка 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, мне нужно запустить два процесса одновременно:

  1. Поймать входящий поток и обработать данные
  2. Следите за временем и вставляйте любые данные (если они есть) в базу данных на регулярной основе

Можно ли проверить, сколько байтов осталось в потоке перед запуском fread() и продолжить мой цикл while, если unread_bytes '== 0? Или можно установить какой-то тайм-аут на fread(), не нарушая соединение всего потока? Я открыт для того, чтобы PHP не был правильным языком, чтобы делать то, что я делаю, но это то, что я знаю, поэтому я действительно хотел бы использовать его, если это возможно.

Теги:
sockets
stream
timeout
fread

1 ответ

1
Лучший ответ

Иногда формулирование вопроса для других - это лучший способ задать вам правильный путь, чтобы найти правильный ответ для себя. Я заметил, что один из элементов массива stream_get_meta_data() был "blocking" => "true", и поскольку я только что закончил спрашивать о разблокировке fread(), это заставило меня искать способ установить "блокировку" на " ложный."

Использовать: stream_set_blocking($fp, 0); , после fopen() но до цикла

(docs)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню