【问题标题】:Apache Server Timeout with an error message "The page cannot be displayed" for a PHP scriptPHP 脚本的 Apache 服务器超时并显示错误消息“无法显示页面”
【发布时间】:2009-09-17 06:27:42
【问题描述】:

我正在尝试使用 PHP 将简单 Perl 脚本的输出重定向到 Web 浏览器。 Perl 脚本有时需要 2-3 小时才能执行并将输出显示到屏幕上。 到这个时候,我猜 Apache Server 只是超时并显示上述错误消息。

这里是示例代码片段。

 # 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);

【问题讨论】:

    标签: php apache


    【解决方案1】:

    你为什么要通过网络服务器运行它?你应该以不同的方式运行它。网络服务器应使用 startfile 或 db 条目向 perl 脚本发出信号。脚本的包装器在 cron 上运行并查找启动文件。当它看到它时,它会启动 perl 进程。 perl proc 写入另一个 Web 可访问文件。在您的 web 应用程序发出 perl 脚本启动的信号后,它会转发到一个页面,该页面使用 settimeout 每 1 秒 ajaxes perl 文件的输出。

    编辑

    考虑使用 Ajax,您不必保持与服务器的连接打开,而是通过大量请求来访问它:

        <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>
    

    【讨论】:

    • 实际是项目需求。我们的 UI 允许用户通过浏览器选择测试用例,也允许他从浏览器执行相同的测试。现在,它应该将输出显示回浏览器窗口。此应用程序可以正常工作到 2-3 小时,然后它会简单地显示“页面无法显示”错误消息。
    • 拜伦的解决方案完全可以做到这一点,您只需将测试用例的输出通过管道传输到文件或数据库,然后使用 AJAX 将其提供给浏览器。
    【解决方案2】:

    另一种可能性是安排您的 perl 脚本连续产生输出。

    #!/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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 2014-04-02
      • 2013-09-20
      • 1970-01-01
      • 2016-05-11
      • 2021-06-09
      • 1970-01-01
      相关资源
      最近更新 更多