【问题标题】:can sinatra re-stream output from php script through ajax?sinatra 可以通过 ajax 重新流式传输 php 脚本的输出吗?
【发布时间】:2011-05-14 19:40:15
【问题描述】:

我在服务器 A 上运行了一个 php 脚本,大约需要 15 分钟才能完成。我通过网络浏览器运行脚本,它以块的形式向浏览器发送输出(一些 php 命令完成)。请参阅下面的块示例。该脚本创建 DB2 数据库,总共需要几个步骤。

现在我通过 AJAX 从服务器 B 上的 sinatra 运行相同的脚本。它工作正常,但是一旦 php 脚本完成,我就会得到全部输出(我称之为所有块)。

有没有什么方法可以设置 sinatra/ajax,使其工作方式与直接从浏览器(而不是从 sinatra)启动脚本一样?所以我可以在每个块完成后看到结果,而不是在整个 ajax 调用完成时。

HAML 文件(提取)

:javascript
  function loadXMLDoc2(mode)
  {
    if (window.XMLHttpRequest)
      {// code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
      }
    else
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    xmlhttp.onreadystatechange=function()
      {
      document.getElementById("db2").innerHTML="<BLINK> processing</BLINK> "+mode+" procedure";
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        document.getElementById("db2").innerHTML=xmlhttp.responseText;
        }
      }
    xmlhttp.open("GET","/ajaxdb2?mode="+mode,true);
    xmlhttp.send();
     }

    %td 
      %button{:type => "button", :onclick => "loadXMLDoc2('create')"}
        create DB2
      %br

ruby 代码(摘录)

get '/ajaxdb2?' do

  execute_db2_script(params['mode'].downcase)
end 

def execute_db2_script(mode)

  if not (mode == 'clear')

    db2_database = 'RATIONAL'
    url = "http://db2express/imacs/radek/db2.rft/rationalTest.php?mode=#{mode}&database=#{db2_database}"
uri = URI.parse(url)
start = Time.new

response = Net::HTTP.start(uri.host, uri.port) do |http|
  http.open_timeout =  5
  http.read_timeout = 1500
  http.request_get(uri.request_uri)
end

stop = Time.new

return "#{response.body} <BR>processed in #{stop - start} seconds"
 else
  return "DB2 results"
 end
end

PHP 代码示例(2 块)

flush_buffers();

$output = array();
$shellOutput = exec("echo 'password' | sudo -su db2inst1 -S '/opt/ibm/db2/V9.7/bin/db2 deactivate database $databaseName'", $output);

echo "<pre>Output = " . print_r($output,1) . "</pre>";
if( strpos($output[0],'DB20000I') === false && strpos($output[0],'SQL1496W') === false && strpos($output[0],'SQL1013N') === false && strpos($output[0],'SQL30061N') === false ){
    echo("Could not deactivate database.");
}
flush_buffers();


$output = array();
$shellOutput = exec("sudo -su db2inst1 -S '/opt/ibm/db2/V9.7/bin/db2 drop database $databaseName'", $output);
echo "<pre>Output = " . print_r($output,1) . "</pre>";
if( strpos($output[0],'DB20000I  The DROP DATABASE command completed successfully') === false && strpos($output[0],'SQL1013N') === false && strpos($output[0],'SQL30061N') === false ){
    echo("Dropping of the database was not successful.");
}

【问题讨论】:

  • 您能发布您的 PHP 脚本和 AJAX 代码吗?另外,我不确定“通过浏览器运行脚本并将输出以块的形式发送到浏览器”是什么意思。我假设 PHP 脚本存储在您的服务器上,因此由服务器运行以响应客户端请求。
  • @Jergason:您几乎可以阅读新问题 :-)
  • 有人知道怎么做吗?

标签: php ajax sinatra


【解决方案1】:

我现在在家,我的代码正在工作,但您可以通过管道将输出传输到日志文件(或使用 popen)然后在日志文件行增长/管道时显示日志文件行,使用会话行持有者...

我使用了一个 jquery ui 进度条(可选),它与一个 ajax 调用(在面向客户端的 jquery 中)相关联,并带有一个启动 exec 的 go 按钮,然后等到会话变量中包含字符串“完成并且我每次调用会话变量时,都有一个 PHP $.ajax 获取页面输出会话变量的内容。

一熄火

<?
session_start();
$_SESSION['latestline']="starting";
exec("somelongjobmultiline >c:\temp\log.log");
?>

会话变量更新器

<?
//session getter for the $.ajax call will continue til its saying "complete"
session_start();
//code to go to the log.log or read the popen output
echo $_SESSION['latestline'];
?>

我明天会发布我使用的实际代码

【讨论】:

    【解决方案2】:

    好的,它在 PHP 中:

    对于演示:创建一个 C:\Temp\sleep.bat 并在其中包含行这将需要 5 秒来轮询结果 - 确保没有名为 C:\Temp\info.log 的文件

    @echo. > C:\Temp\info.log
    @echo working start > C:\Temp\info.log
    @ping 123.45.67.89 -n 1 -w 1000 > nul
    @echo working 1 second > C:\Temp\info.log
    @ping 123.45.67.89 -n 1 -w 1000 > nul
    @echo working 2 seconds > C:\Temp\info.log
    @ping 123.45.67.89 -n 1 -w 1000 > nul
    @echo working 3 seconds > C:\Temp\info.log
    @ping 123.45.67.89 -n 1 -w 1000 > nul
    @echo working 4 seconds > C:\Temp\info.log
    @ping 123.45.67.89 -n 1 -w 1000 > nul
    @echo done (after 5) > C:\Temp\info.log
    

    然后是 index.php、launchprocess.php、getprocessstatus.php、style.css 任何你喜欢但在同一个文件夹中的地方

    index.php

    <?php
        //index.php
        session_start();
        $_SESSION['out']="";
    
        echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
        echo "<html>\n";
        echo "<head>\n";
        echo "    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n";
        echo "    <title>Demo</title>   \n";
        echo "\n";
        echo "    <link rel=\"stylesheet\" href=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/themes/base/jquery-ui.css\" media=\"screen\" />\n";
        echo "    <script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js\"></script>\n";
        echo "    <script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js\"></script>\n";
        echo "  \n";
        echo "  <link rel=\"stylesheet\" href=\"style.css\" media=\"screen\" />\n";
    
        echo "<script>\n";
        echo "  $(document).ready(function(){\n";
        echo "      \n";
        echo "      $('#go').click(function(){\n";
        echo "          $.ajax({\n";
        echo "              cache: false,\n";
        echo "              type: 'post',\n";
        echo "              url: 'launchprocess.php',\n";
        echo "              beforeSend: start_display()\n";
        echo "          });\n";
        echo "      });\n";
        echo "      \n";
        echo "  });\n";
        echo "\n";
        echo "  var interval='';\n";
        echo "  var counter=1;\n";
        echo "      \n";
        echo "  function start_display() {\n";
        echo "      $(\".button\").val(\"...hold on a minute\"); \n";
        echo "      $(\".button\").attr(\"disabled\", true); \n";
        echo "      if (interval==\"\") {\n";
        echo "          interval=window.setInterval(\"display()\",200);\n";
        echo "      } else {\n";
        echo "          stop_display();\n";
        echo "      }\n";
        echo "  }\n";
        echo "\n";
        echo "  function stop_display() {\n";
        echo "      $(\".button\").val(\"Click to go!\"); \n";
        echo "      $(\".button\").attr(\"disabled\", false); \n";
        echo "      if (interval!=\"\") {\n";
        echo "          window.clearInterval(interval);\n";
        echo "          interval=\"\";\n";
        echo "      }\n";
        echo "  }\n";
        echo "\n";
        echo "  function display() {\n";
        echo "      counter ++; \n";
        echo "      if (counter=='100') {\n";
        echo "          stop_display();\n";
        echo "          $('#text').html('Timeout');\n";
        echo "      }\n";
        echo "      $.ajax({\n";
        echo "          cache: false,\n";
        echo "          type: 'get',\n";
        echo "          url: 'getprocessstatus.php',\n";
        echo "          success: function(response) {\n";
        echo "              $('#text').html(response);\n";
        echo "              if (response=='100' || response =='done' || response =='complete') {\n";
        echo "                  stop_display();\n";
        echo "                  $('#text').html('Done!');\n";
        echo "              }\n";
        echo "          }\n";
        echo "      });\n";
        echo "  }\n";
        echo "  \n";
        echo "</script>\n";
    
        echo "\n";
        echo "</head>\n";
        echo "<body>\n";
        echo "\n";
        echo "<div id=\"step\">\n";
        echo "      <h1>Run Demo</h1>\n";
        echo "      <input type=\"button\" value=\"Click to go!\" class=\"button green\" id=\"go\">\n";
        echo "      <div id=\"text\"></div>\n";
        echo "</div>\n";
        echo "\n";
        echo "</body>\n";
        echo "</html>\n";
    ?>
    

    启动进程.php

    <?php
        // file: launchprocess.php
        session_start();
    
        function command($cmd){
            session_start();
            $_SESSION['out'] = "";
            session_commit();
    
            session_write_close();
            exec($cmd,$out);
            session_commit();
    
            foreach($out as $line){
                if ($line) $store .= $line . "<br>";
            }       
        }
    
        session_start();    
        $_SESSION['out'] = "setting up";
        session_commit();
    
        command("C:\\Temp\\Sleep.bat"); 
    
        session_start();    
        $_SESSION['out'] = "done";
        session_commit();
    ?>
    

    getprocessstatus.php

    <?php
        // file: getprocessstatus.php
        session_start();
    
        if ($_SESSION['out']) echo $_SESSION['out'];
        else {
            $filename = "C:\\Temp\\info.log";
            if (is_file($filename)){
                $handle = fopen($filename, "r");
                echo fread($handle, filesize($filename));
                fclose($handle);
            }
            else{
                echo "no file";
            }
        }
    ?>
    

    style.css

    body {
            margin: 100px 0 0 200px;
    }
    
    h1 {
        font-family: calibri, arial;
        font-weight: bold;
    }
    
    div {
        font-family: calibri, arial;
        font-weight: bold;
    }
    
    #response {
        width: 500px;
        height: 20px;
        backgorund: #fff;
        background: -webkit-gradient(linear, 0 0, 0 100%, from(#f1f1f1), to(#fff));
        background: -moz-linear-gradient(top, #f1f1f1, #fff);
        border: 1px solid #ccc;
        border-radius: 2px;
        -moz-border-radius: 2px;
        margin: 0 0 20px 0;
        display: none;
    }
    #response div {
        height: 100%;
        width: 0;
        border: none;
        background: #84D700;
        -moz-box-shadow: 2px 0 5px #ccc;
        -webkit-box-shadow: 2px 0 5px #ccc;
        box-shadow: 2px 0 5px #ccc;
    }
    #loader {
        vertical-align: middle;
        margin: 0 10px 0 0;
        display: none;
    }
    
    .button {
        font-family: calibri, arial;
        font-weight: bold;
        color: white;
        font-size: 18px;
        padding:7px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        width: 220px;
    }
    
    .green {
        background-color: #9BBB59;  
        border: solid 3px #71893F;  
    }
    
    .purple {
        background-color: #8064A2;  
        border: solid 3px #5C4776;  
    }
    
    .blue {
        background-color: #4F81BD;  
        border: solid 3px #385D8A;  
    }
    
    .cyan {
        background-color: #4BACC6;  
        border: solid 3px #357D91;  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-30
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多