Search code examples
phpprocessstreampipereal-time

Read realtime whole output in stream


Note: this post have difference with this post whose accepted answer just read each line a time.

I have to slice 3D models for 3D printing on the server side, the process will cost some time. So I have to show the process for the user, I use the redis to store the process. I want to refresh the process every 0.5 seconds. For example, sleep 0.5 sec, read all the content in the pip and process it each time.

For now I have tryed the below two, the first one will hold until it finished. the second use while is not a proper way, it will keep writing the redis will cause the client read process request hold to the end.

I've tryed these two:

The first will hold until the command finished.

$descriptorspec = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("pipe", "w")    //here curaengine log all the info into stderror
);
$command = './CuraEngine slice -p -j ' . $fdmprinterpath . ' -j ' . $configpath . ' -o ' . $gcodepath . ' -l ' . $tempstlpath;
$cwd = '/usr/local/curaengine';
$process = proc_open($command, $descriptorspec, $pipes, $cwd);
if(is_resource($process))
{
    print stream_get_contents($pipes[1]);  //This will hold until the command finished.
}

and the second implemented as this post will each time one line.

  $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")    //here curaengine log all the info into stderror
    );
    $command = './CuraEngine slice -p -j ' . $fdmprinterpath . ' -j ' . $configpath . ' -o ' . $gcodepath . ' -l ' . $tempstlpath;
    $cwd = '/usr/local/curaengine';
    $process = proc_open($command, $descriptorspec, $pipes, $cwd);
    if(is_resource($process))
    {
        while ($s = fgets($pipes[1])) {
            print $s;
            flush();
        }
    }

Solution

  • use fread() to replace fgets().