может sinatra повторно направить вывод из сценария php через ajax? - PullRequest
1 голос
/ 24 ноября 2010

У меня есть скрипт php, работающий на сервере A, который занимает 15 минут, чтобы закончить. Я запускаю сценарий через веб-браузер, и он отправляет вывод в браузер блоками (как завершили некоторые команды php). Ниже приведен пример блоков. Сценарий создает базу данных DB2, и для его выполнения требуется всего несколько шагов.

Теперь я запускаю тот же скрипт из sinatra на сервере B через AJAX. Он работает нормально, но я получаю всю выходную информацию (все блоки, как я ее называю), когда скрипт 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

код рубина (извлечение)

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 блока)

<code>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) . "
"; if (strpos ($ output [0], 'DB20000I') === false && strpos ($ output [0], 'SQL1496W') === false && strpos ($ output [0], 'SQL1013N') == = false && strpos ($ output [0], 'SQL30061N') === false) { echo («Не удалось деактивировать базу данных.»); } flush_buffers (); $ output = array (); $ shellOutput = exec ("sudo -su db2inst1 -S '/opt/ibm/db2/V9.7/bin/db2 удалить базу данных $ databaseName'", $ output); echo "
Output = " . print_r($output,1) . "
"; if (strpos ($ output [0], 'DB20000I Команда DROP DATABASE выполнена успешно') === false && strpos ($ output [0], 'SQL1013N') === false && strpos ($ output [0], 'SQL30061N') === false) { echo («Удаление базы данных не было успешным.»); }

Ответы [ 2 ]

1 голос
/ 08 апреля 2011

хорошо, это в 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";
?>

launchprocess.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;  
}
1 голос
/ 07 апреля 2011

Я сейчас дома, и мой код на работе, но вы делаете это, передавая выходные данные в файл журнала (или используя popen ), затем показывая строки файла журнала по мере их роста / передачи с использованием держатель строки сеанса ...

Я использовал индикатор выполнения jquery ui (необязательно), привязанный к вызову ajax (в jquery, обращенном к клиенту) кнопкой go, которая запускала exec, затем ждал, пока в переменной сеанса не будет завершена строка «я», и я имел один PHP $ .ajax get page, выводящий содержимое переменной сеанса каждый раз, когда она вызывалась.

один выключен, выключен

<?
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'];
?>

Я выложу код, который я использую завтра

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...