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();
}
}
use
fread()
to replacefgets()
.Take a look at the Symfony component
Process
. It provides easy async process, and real-time process output, among other things. For example:You should disable output buffering first by adding this line to the start of your code:
With that line added, your second code should be able to stream.
Unfortunately, even with output buffering disabled, the result of output streaming is browser dependent. I tested several browsers, both desktop and mobile, and found that output streaming works in Chromium-based browsers, but doesn't work in Firefox.
Because it is browser dependent, the functions you use, be it
fgets()
orfread()
, are irrelevant. If you need the streaming to work on other browsers as well, you can encapsulate it with XMLHttpRequest.Here is an example that works with Chromium-based browsers:
The HTML counterpart makes it work with other browsers:
You can use the same mechanism to create a progress bar like I mentioned.