简体   繁体   中英

Apache Server Timeout with an error message “The page cannot be displayed” for a PHP script

I'm trying to redirect output of a simple Perl script to a web browser using PHP. The Perl script sometimes take 2-3 hours to execute and show output to the screen. By this time, I guess Apache Server simply timesout and displays an error message discribed above.

Here is the sample code snipet.

 # The tmpOutput.txt contains output of a Perl script.
 # Read a file using an handle.
$handle = popen("tail -f tmpOutput.txt", 'r');

 # Check if read handle has been allocated properly.
if ($handle) {
    # to prevent the code from hanging up when the response is slow.
    stream_set_blocking($handle, FALSE);

    # Set the stream timeout period to 24 hours i.e. 86400 seconds.
    stream_set_timeout($handle, 86400);

    # Get the available stream meta data information.
    $info = stream_get_meta_data($handle);

    # While there's no end of file, read the file contents and redirect them to standard display.
    while((!feof($handle)) && (!$info['timed_out'])) {
        $buffer = fgets($handle);
        echo "$buffer<br/>\n";
        ob_flush();
        flush();

        $info = stream_get_meta_data($handle);
    }

    # Check if some issue while streaming data.
    if ($info['timed_out']) {
        echo 'Connection timed out!';
    }
}

 # Close the file handle.
pclose($handle);

why are you trying to run this thru the web server? You should run this a little differently. The webserver should signal the perl script to start using a startfile or db entry. A wrapper for the script runs on cron and looks for the startfile. when it sees it, it starts the perl process. The perl proc writes to another web accessible file. after your web app signals the perl script to start, it forwards to a page that ajaxes the output of perl file every 1 second using settimeout.

Consider using Ajax you don't have to keep a connection open to the server, but instead you hit it with a multitude of requests:

    <script type="text/javascript">
        function getXmlHttp()
        {
                    var xmlHttp;
            try{    
                xmlHttp=new XMLHttpRequest();// Firefox, Opera 8.0+, Safari
            }
            catch (e){
                try{
                    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
                }
                catch (e){
                    try{
                        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch (e){
                        alert("No AJAX!?");
                        return false;
                    }
                }
            }
            return xmlHttp;
        }

        function Ajax(){
        var xmlHttp = getXmlHttp();
        xmlHttp.onreadystatechange=function(){
            if(xmlHttp.readyState==4){
                document.getElementById('logwindow').innerHTML=xmlHttp.responseText;                    
                setTimeout('Ajax()',1000);
            }
        }
        /* NAME OF OUTPUT FILE HERE */
        xmlHttp.open("GET","session.log?" + Math.random(),true);
        xmlHttp.send(null);
        }


        Ajax();
        </script>

Another possibility is to arrange for your perl script to continuously produce output.

#!/usr/bin/perl
my $heartbeat_pid = fork();
if ($heartbeat_pid == 0) {    # child process to print a newline every 10 minutes
    my $output_freq = 600;
    for (;;) {
        sleep $output_freq;
        print "\n";
    }
}
&the_main_routine_that_takes_a_long_time_to_produce_output();
kill 9, $heartbeat_pid;     # clean up child at end of script

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM