Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Is there a way in PHP to take some action (mysql insert for example) if there is no new requests for say 1 second?

What I am trying to achieve is to determinate beginning and the end of image sequence sent from a IP camera. Camera sends series of images on detected movement and stops sending when movement stops. I know that camera makes 5 images per second (every 200ms). When there is no new images for more than 1 sec I want to flag last image as end of the sequence, insert a record in mysql, place img in appropriate folder (where all other imgs from the same sequence are already written) and instruct app to make a MJPEG clip of images in that folder.

Right now I am able to determine the first image in the sequence using Alternative PHP cash to save reference time from the previous request but the problem is because next image sequence can happen hours later and I can not instruct PHP to close the sequence if there is NO requests for some time, only when first request of the new sequence arrives.

I really need help on this. My PHP sucks almost as my English... :)

Pseudo code for my problem:

<?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. */

?>
like image 684
Gawran Avatar asked Nov 24 '14 01:11

Gawran


1 Answers

Could you make each request usleep 1.5 seconds before exiting, and as a last step check to see if the sequence timestamp was updated? If yes, exit and do nothing. If no, save the sequence to mysql. (This will require mutexes, since each http request will be checking and trying to save the sequence, but only one must be allowed to.)

This approach would merge the sub-file/script into the php code (single codebase, easier to maintain), but it can possibly balloon memory use (each request will stay in memory 1.5 seconds, which is a long time for a busy server).

Another approach is to make the sub-file/script into a loopback request on the localhost http server, with presumably a much smaller memory footprint. Each frame would fire off a request to finalize the sequence (similarly again, with mutexes).

Or maybe create a separate service call that checked and saved all sequences, and have a cron job ping it every few seconds. Or have each frame ping it, if a second request can detect that the service is already running it can exit. (share state in the APC cache)

Edit: I think I just suggested what bytesized said above.

like image 139
Andras Avatar answered Oct 06 '22 01:10

Andras