2016-03-15 5 views
4

У меня есть сервер и создайте для него веб-интерфейс, если пользователь нажимает кнопку перезагрузки на странице, тогда пользователь перенаправляется на reboot.php, где предполагается, что он будет показывать счетчик gif до сервер снова доступен, и сервер перезагружается через выполнение оболочки. Если сервер доступен, то мне нужно перенаправить на main.phpПоказывать страницу ожидания во время перезагрузки сервера

Итак, я создал следующую функцию. Функция начинается с таймаута в 5 секунд, потому что в противном случае она мгновенно загрузится main.php, потому что команда перезагрузки требует времени.

reboot.php

$ret = false; 

    test(); 

    function test() 
    { 
     setTimeout 
     (
      function() 
      { 
       $ret = ping("www.google.de"); 
       if ($ret === false) 
       { 
        test(); 
       } 
       else 
       { 
        window.location.href = "main.php"; 
       } 
      }, 
      3000 
     ); 
    } 

    function ping(url) 
    { 
     $.ajax 
     (
      { 
       url: url, 
       success: function(result) 
       { 
        alert('reply'); 
        return true; 
       },  
       error: function(result) 
       { 
        alert('timeout/error'); 
        return false; 
       } 
      } 
     ); 
    } 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
    <div class="col-lg-6 col-lg-offset-3" id="mydiv"> 
 
     <div class="mydiv_inhalt"> 
 
      <h2>Rebooting...</h2> 
 
      <p>This can take about 2 minutes.</p> 
 
      <center> 
 
       <div class="waiting" id="waiting" style="margin-top:30px; margin-left: 0px;"> 
 
        <center><img class="loading_table" src="http://www.securenet.com/sites/default/files/spinner.gif" alt="spinner gif"></center> 
 
       </div> 
 
      </center> 
 
     </div> 
 
    </div>

ajax.php

$cmd  = filter_input(INPUT_POST, "cmd"); 
if (isset($cmd) && $cmd == "check_online_status") 
{ 
    echo "true"; 
} 

В моей ajax.php Я просто возвращаю «истину», если вызов был успешным. Однако моя логика не работает, кажется, что мой код только пытается сделать один звонок моему ajax.php, а затем никогда не пытается снова, и я получаю net::ERR_CONNECTION_REFUSED в консоли.

Я добавил много предупреждений в свой код, но они не выполняются, поэтому я думаю, что он не пытается позвонить ajax.php во второй раз после получения net::ERR_CONNECTION_REFUSED.

Моя единственная идея будет ждать достаточно времени, а затем перенаправить на main.php, но это не является хорошим решением, потому что нужно везение, что, если время не было достаточно и т.д.

ответ

5

Давайте подведем проблемы в вашем коде:

  • вам нужно использовать setInterval для выполнения функции каждые х секунд
  • на основе AJAX запрос является асинхронным, и он должен оставаться в этом роде. Вы не можете ожидать, возвращаемое значение из функции обратного вызова, вместо этого, вы должны действовать в обратного вызова

Результирующий код способ проще:

var pingUrl = "www.google.de"; 
var targetUrl = "main.php"; 
setInterval(ping, 3000); 

function ping() { 
    $.ajax({ 
     url: pingUrl, 
     success: function(result) { 
      window.location.href = targetUrl; 
     } 
    }); 
} 
+0

setTimeout (function() {setInterval (ping, 2000);}, 8000); сначала будет ждать 10 секунд, а затем ping сервер каждые 2 секунды. – diynevala

+0

Ничего себе, это сработало. В заключение! Спасибо, сэр. – Black

0

Если сервер перезагружается, обычно вам понадобится какой-то IP-адрес с отказоустойчивостью или, по крайней мере, кеширующий прокси-сервер перед сервером приложений (в данном случае OpenERP), чтобы сообщить пользователю, что он не работает. В противном случае, пока сервер отключен, вы получите только общее сообщение об ошибке браузера, которое будет возвращено клиенту, например «сервер не найден» или аналогичный.

Короче говоря, лучший способ сделать это - иметь еще один физический/виртуальный сервер, расположенный перед сервером приложений, который «всегда» (или кластер серверов, которые перезагружаются независимо), так что вы всегда есть что-то, разрешающее доменное имя, или может переступить к резервной копии, если первичный файл отключен из-за сбоев или перезагрузки.

Надеется, что это помогает

+1

OP хочет JS-страница, которая будет загружена перед перезагрузкой, и выполнить запрос на сервере, подобный ping, чтобы получить ответ, прежде чем запустить JE redi rect ... – Blag

+0

Да, им жаль, если я не выразил правильно, но да, это моя цель. Благ прав. – Black

0

SetTimeout запускает функцию только разы

вы можете использовать setInterval вместо SetTimeout

+0

, если вы прочитаете код, вы увидите, что он выполняет рекурсивную настройку setTimeout – Soren

+0

@Soren. Начальная версия этого вопроса не кодирует никаких рекурсивных. – Kwan

+1

прочитайте еще раз: 'function test() {.... if (=== false) test(); ... '- поэтому он пытается рекурсивно настроить новый тайм-аут, используя функцию' test', если условие ложно .... – Soren

0

Этого код должен работать. То, что я сделал:

  • Использование setInterval вместо setTimeout выполнить ping -функции каждые х секунд.
  • Функция $.post выполняется асинхронно (запрос ajax).Это означает, что вы не можете использовать цикл while, как вы это делали (кроме того, что вы устанавливаете jQuery для синхронного вызова).
  • Пожалуйста, не используйте Umlaute (äöü) в своем коде. Ничего хорошего из этого не выйдет.

var timeoutCounter = 0; 

var interval = setInterval(function() { 
    ping(10); 
}, 5000); 

function ping(maxTimeouts) { 
    $.post(
     'ajax.php', 
     { cmd: "check_online_status" }, 
     function(data, status) { 
      if (status == "success") { 
       window.location.href = 'main.php'; 
       clearInterval(interval); 
      } else { 
       timeoutCounter++; 

       if (timeoutCounter >= maxTimeouts) { 
        alert("Max Timeouts ("+ maxTimeouts + ") exceeded!"); 
        clearInterval(interval); 
       } 
      } 
     } 
    ); 
} 
+0

Почему downvote? Почему у всех ответов есть понижение? OP? – sjkm

+0

Я не знаю, я уверяю вас, что нисходящие нити не от меня @sjkm. – Black

+1

@EdwardBlack Спасибо, что сообщили мне! Система голосования не всегда лучшая вещь ... – sjkm

0

Это может помочь, как это ближе всего к пингом вы можете сделать с JS: https://github.com/jdfreder/pingjs

Используйте запасной вариант как рекурсивный обеденного снова часть, и быть осторожными, чтобы не перенаправлять на быстрый в первой части.

0

Функция ping должна быть синхронной: param async: false в запросе ajax.

С запросом асинхронного запроса вы никогда не вводите условие if ($ret === false), поэтому рекурсивный вызов не может быть выполнен.

Кроме того, возврат значения в обратные вызовы success или error не приводит к тому, что функция ping возвращает требуемое значение.

Вы должны переписать ping функцию следующим образом:

function ping(url) 
{ 
    var ret = false; 
    $.ajax 
    (
     { 
      async: false, 
      url: url, 
      success: function(result) 
      { 
       alert('reply'); 
       ret = true; 
      },  
      error: function(result) 
      { 
       alert('timeout/error'); 
       ret = false; 
      } 
     } 
    ); 
    return ret; 
} 
+0

Да, я протестировал его. Если вызов ajax терпит неудачу, вы находитесь в обратном вызове 'error'. Когда ajax заканчивается правильно (перезагрузка сервера завершена), вы находитесь в обратном вызове 'success', поэтому он возвращает' true' –

0

Вы не можете вернуться синхронно из ping, как вы делаете - возвращаемое значение является непрестанно undefined в функции тестирования, если вы установите флажок значение с помощью отладчика. Причина в том, что $.ajax не является синхронным вызовом.

Вы не должны (плохой стиль) полагаться на синхронный apis при создании javascript, поэтому вам нужно подумать о том, как сделать то же самое с использованием шаблона асинхронизации.

Для дальнейшего чтения, посмотрите на этот вопрос: How do I return the response from an asynchronous call?

Перепишите свой код, чтобы использовать шаблон асинхронной, что-то вроде этого;

$ret = false; 

function rebooted(){ console.log("Reboot complete")}; 
test(rebooted); 

function test(okcb) 
{ 
    setTimeout 
    (
     function() 
     { 
      ping("www.google.de", 
       function(){ $ret=true; okcb(); }, 
       function(){ test(okcb);} 
      ); 
     }, 
     3000 
    ); 
} 

function ping(url, yeah, nooo) 
{ 
    $.ajax 
    (
     { 
      url: url, 
      success: function(result) 
      { 
       console.log('reply'); 
       yeah(); 
      },  
      error: function(result) 
      { 
       console.log('timeout/error'); 
       nooo(); 
      } 
     } 
    ); 
} 
1

@EdwardBlack Fisrt вы должны Ассинг.рисунок для изображения тег с идентификатором, то в этом изображении тега вы передать стиль = "дисплей: нет"

<img id="imgid" src="" style="display:none">

function ping(url) { 
 

 
     $.ajax({ 
 
       
 
       url: url, 
 
       beforeSend : function(){ 
 
        $('#imgid').css({'display':'block'}); //or 
 
        $('#imgid').css('display', 'block'); // any one 
 
       }, 
 
       success: function() { 
 
        alert('reply'); 
 
        return true; 
 
       },  
 
       error: function() { 
 
        alert('timeout/error'); 
 
        return false; 
 
       } 
 
      }); 
 
    }