如果unread_bytes == 0,则取消阻塞fread(),不会导致流连接超时


Unblock fread() if unread_bytes == 0, without timing out stream connection

我正在尝试处理一个流,它向我发送离散的信息包,但信息包之间的持续时间未知——比如,在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),并允许下面的代码检查时间,并根据需要进行DB插入。

TL;DR,我需要两个进程同时运行:

  1. 捕获传入流并处理数据
  2. 密切关注时间,并定期将任何已到达的数据(如果有的话)插入数据库

是否有可能在开始fread()之前检查流中剩下多少字节并继续我的while循环如果unread_bytes' == 0?或者是否可以在不中断整个流连接的情况下,专门为fread()设置某种超时?我对PHP可能不是我所做的事情的正确语言持开放态度,但这是我所知道的,所以如果可能的话,我真的很想使用它。

有时候,为别人提出一个问题是让你走上正确的轨道,为自己找到正确答案的最好方法。我注意到stream_get_meta_data()数组中的一个元素是"blocking"=>"true",并且由于我刚刚完成了关于解除fread()阻塞的询问,这让我寻找一种将"blocking"设置为"false"的方法。

使用:stream_set_blocking($fp, 0);,在fopen()之后,在循环之前

(文档)