如果有一段时间没有新请求,有没有办法执行 PHP 脚本


Is there a way to execute PHP script if there is NO new requests for some time?

如果没有新的请求,比如 1 秒,PHP 中有没有办法采取一些操作(例如 mysql 插入)?

我试图实现的是确定从IP摄像机发送的图像序列的开始和结束。相机在检测到的移动时发送一系列图像,并在移动停止时停止发送。我知道相机每秒拍摄 5 张图像(每 200 毫秒)。当超过 1 秒没有新图像时,我想将最后一个图像标记为序列的末尾,在 mysql 中插入一条记录,将 img 放在适当的文件夹中(同一序列中的所有其他 img 已经写入)并指示应用程序在该文件夹中制作图像的 MJPEG 剪辑。

现在,我能够使用替代 PHP 现金确定序列中的第一个图像,以节省上一个请求的参考时间,但问题是因为下一个图像序列可能会在几个小时后发生,并且我无法指示 PHP 关闭序列如果有一段时间没有请求,只有当新序列的第一个请求到达时。

我真的需要这方面的帮助。我的PHP几乎和我的英语一样糟糕... :)

我问题的伪代码:

<?php
  if(isset($headers["Content-Disposition"]))
    {
        $frame_time = microtime(true);
      if(preg_match('/.*filename=['''"]([^'''"]+)/', $headers["Content-Disposition"], $matches))
      { $filename = $matches[1]; }
      else if(preg_match("/.*filename=([^ ]+)/", $headers["Content-Disposition"], $matches))
      { $filename = $matches[1]; }
    }
  preg_match("/(anpr[1-9])/", $filename, $anprs);
  $anpr = $anprs[1];
  $apc_key = $anpr."_last_time"; //there are several cameras so I have to distinguish those  
  $last  = apc_fetch($apc_key);
  if (($frame_time - $last)>1)
         {
            $stream = "START"; //New sequence starts
         } else {
            $stream = "-->"; //Streaming
         };
   $file = fopen('php://input', 'r');
   $temp = fopen("test/".$filename, 'w');
   $imageSize = stream_copy_to_stream($file, $temp); //save image file on the file system
   fclose($temp);
   fclose($file);
   apc_store($apc_key, $frame_time); //replace cashed time with this frame time in APC
  // here goes mysql stuff...
  /* Now... if there is no new requests for 1 second $stream = "END";  
  calling app with exec() or similar to grab all images in the particular folder and make 
 MJPEG... if new request arrives cancel timer or whatever and execute script again. */
?>

您能否在退出前 1.5 秒使每个请求进入休眠状态,并作为最后一步检查序列时间戳是否已更新? 如果是,请退出,不执行任何操作。 如果没有,请将序列保存到 mysql。 (这将需要互斥锁,因为每个 http 请求都将检查并尝试保存序列,但必须只允许一个。

这种方法会将子文件/脚本合并到 php 代码中(单个代码库,更易于维护),但它可能会膨胀内存使用量(每个请求将在内存中保留 1.5 秒,这对于繁忙的服务器来说是很长的时间)。

另一种方法是将子文件/脚本转换为本地主机 http 服务器上的环回请求,内存占用量可能要小得多。 每个帧都会触发一个请求来完成序列(同样,使用互斥体)。

或者可以创建一个单独的服务调用来检查并保存所有序列,并每隔几秒钟让一个 cron 作业 ping 它。 或者让每个帧 ping 它,如果第二个请求可以检测到服务已经在运行,它可以退出。 (APC 缓存中的共享状态)

编辑:我想我只是建议了上面所说的字节化。

如果在脚本存储帧后保持脚本运行 1 秒以检查更多添加的帧,该怎么办?我想您可能希望在 1 秒到期之前关闭连接,但 tomlgold2003 和 arr1 为您提供了答案:http://php.net/manual/en/features.connection-handling.php#93441

我认为这对你有用:

<?php
ob_end_clean();
header("Connection: close'r'n");
header("Content-Encoding: none'r'n");
ignore_user_abort(true); // optional
ob_start();
// Do your stuff to store the frame
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();     // Strange behaviour, will not work
flush();            // Unless both are called !
ob_end_clean();
// The connection should now be closed
sleep(1);
// Check to see if more frames have been added.
?>

如果您的服务器预计会看到高负载,这可能不是您的答案,因为当每秒接收 5 帧时,将有 5 个脚本检查它们是否提交了最后一帧。

将来自相机的每个请求及其所有数据和时间戳存储在一个文件中(以 php 序列化形式)。在 cronjob 中,运行(每 10 秒左右)一个脚本,该脚本读取该文件并查找在下一个请求之前超过一秒的请求。保存此类请求中的数据并删除所有其他请求。