Можно ли пинговать сервер из Javascript?

Я создаю веб-приложение, которое требует, чтобы я проверял, находятся ли удаленные серверы в сети или нет. Когда я запускаю его из командной строки, моя загрузка страницы достигает 60 секунд (для 8 записей она будет масштабироваться линейно с большим количеством).

Я решил пойти по маршруту pinging в конце пользователя. Таким образом, я могу загрузить страницу и просто ждать, пока данные "сервер будут в сети" во время просмотра моего контента.

Если у кого-то есть ответ на вышеупомянутый вопрос, или если они знают, как быстро поддерживать загрузку моей страницы, я бы определенно ее оценил.

Ответ 1

Я нашел кого-то, кто выполняет это с очень умным использованием собственного Image объекта.

Из их источника это основная функция (она имеет зависимости от других частей источника, но вы получаете идею).

function Pinger_ping(ip, callback) {

  if(!this.inUse) {

    this.inUse = true;
    this.callback = callback
    this.ip = ip;

    var _that = this;

    this.img = new Image();

    this.img.onload = function() {_that.good();};
    this.img.onerror = function() {_that.good();};

    this.start = new Date().getTime();
    this.img.src = "http://" + ip;
    this.timer = setTimeout(function() { _that.bad();}, 1500);

  }
}

Это работает на всех тестируемых серверах (веб-серверах, ftp-серверах и игровых серверах). Он также работает с портами. Если кто-либо сталкивается с прецедентом, который терпит неудачу, напишите в комментариях, и я обновлю свой ответ.

Обновить. Предыдущая ссылка удалена. Если кто-либо находит или реализует вышеизложенное, прокомментируйте, и я добавлю его в ответ.

Обновление 2: @trante было достаточно приятно, чтобы предоставить jsFiddle.

http://jsfiddle.net/GSSCD/203/

Обновление 3: @Jonathon создал репозиторий GitHub с реализацией.

https://github.com/jdfreder/pingjs

Обновление 4. Похоже, что эта реализация перестала быть надежной. Люди также сообщают, что Chrome больше не поддерживает все это, бросая ошибку net::ERR_NAME_NOT_RESOLVED. Если кто-то может проверить альтернативное решение, я поставлю это как принятый ответ.

Ответ 2

вы можете попробовать следующее:

поместите ping.html на сервер с содержимым или без него, на javascript выполните следующие действия:

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>

Ответ 3

Вы не можете напрямую "ping" в javascript. Могут быть несколько других способов:

  • Ajax
  • Использование java-апплета с isReachable
  • Написание серверного файла script, который пингует и использует AJAX для связи с вашим serveridescript
  • Возможно, вы также сможете выполнить ping во flash (actionscript)

Ответ 4

Ping - ICMP, но если на удаленном сервере есть какой-либо открытый TCP-порт, он может быть достигнут следующим образом:

function ping(host, port, pong) {

  var started = new Date().getTime();

  var http = new XMLHttpRequest();

  http.open("GET", "http://" + host + ":" + port, /*async*/true);
  http.onreadystatechange = function() {
    if (http.readyState == 4) {
      var ended = new Date().getTime();

      var milliseconds = ended - started;

      if (pong != null) {
        pong(milliseconds);
      }
    }
  };
  try {
    http.send(null);
  } catch(exception) {
    // this is expected
  }

}

Ответ 5

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

Вы даже можете рассчитать время загрузки, используя onload-событие. Здесь пример, как использовать событие onload.

Ответ 6

Чтобы быстро выполнять ваши запросы, кешируйте результаты на стороне сервера ping и обновляйте файл или базу ping каждые пару минут (или, насколько это точно, вы хотите, чтобы это было). Вы можете использовать cron для запуска команды оболочки с вашими 8 пинами и записи вывода в файл, веб-сервер будет включать этот файл в ваше представление.

Ответ 7

Захватывание с помощью решения websocket...

function ping(ip, isUp, isDown) {
  var ws = new WebSocket("ws://" + ip);
  ws.onerror = function(e){
    isUp();
    ws = null;
  };
  setTimeout(function() { 
    if(ws != null) {
      ws.close();
      ws = null;
      isDown();
    }
  },2000);
}

Ответ 8

Проблема со стандартными пинсами - это ICMP, который много мест не пропускает для целей безопасности и трафика. Это может объяснить неудачу.

Ruby до 1.9 имел TCP ping.rb, который будет работать с Ruby 1.9+. Все, что вам нужно сделать, это скопировать его с установки 1.8.7 в другое место. Я только что подтвердил, что это будет выполняться путем проверки моего домашнего маршрутизатора.

Ответ 9

Если вы пытаетесь увидеть, существует ли сервер "существует", вы можете использовать следующее:

function isValidURL(url) {
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        isValid = data.query.results != null;
      },
      error: function(){
        isValid = false;
      }
    });

    return isValid;
}

Это вернет истинное/ложное указание, существует ли сервер.

Если вам требуется время отклика, небольшое изменение будет делать:

function ping(url) {
    var encodedURL = encodeURIComponent(url);
    var startDate = new Date();
    var endDate = null;
    $.ajax({
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) {
        if (data.query.results != null) {
            endDate = new Date();
        } else {
            endDate = null;
        }
      },
      error: function(){
        endDate = null;
      }
    });

    if (endDate == null) {
        throw "Not responsive...";
    }

    return endDate.getTime() - startDate.getTime();
}

Использование тогда тривиально:

var isValid = isValidURL("http://example.com");
alert(isValid ? "Valid URL!!!" : "Damn...");

Или:

var responseInMillis = ping("example.com");
alert(responseInMillis);

Ответ 10

Здесь много сумасшедших ответов, и особенно о CORS -

Вы можете выполнить запрос HTTP HEAD (например, GET, но без полезной нагрузки). См. https://ochronus.com/http-head-request-good-uses/

Ему НЕ нужна проверка перед полетом, путаница из-за старой версии спецификации, см. Почему запрос HEAD для перекрестного происхождения нуждается в предварительной проверке?

Итак, вы можете использовать ответ выше, который использует библиотеку jQuery (не сказал этого), но с помощью

type: 'HEAD'

--- >

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          type: 'HEAD',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>

Вы также можете использовать vanilla js или dojo или что-то еще...

Ответ 11

Я не знаю, какую версию Ruby вы используете, но попробовали ли вы выполнить ping для ruby ​​вместо javascript? http://raa.ruby-lang.org/project/net-ping/

Ответ 12

let webSite = 'https://google.com/' 
https.get(webSite, function (res) {
    // If you get here, you have a response.
    // If you want, you can check the status code here to verify that it '200' or some other '2xx'.
    console.log(webSite + ' ' + res.statusCode)
}).on('error', function(e) {
    // Here, an error occurred.  Check 'e' for the error.
    console.log(e.code)
});;

если вы запустите это с помощью узла, он будет конфисковать журнал 200 до тех пор, пока Google не будет работать.

Ответ 13

Вы можете запустить команду DOS ping.exe из javaScript, используя следующую команду:

function ping(ip)
{
    var input = "";
    var WshShell = new ActiveXObject("WScript.Shell");
    var oExec = WshShell.Exec("c:/windows/system32/ping.exe " + ip);

    while (!oExec.StdOut.AtEndOfStream)
    {
            input += oExec.StdOut.ReadLine() + "<br />";
    }
    return input;
}

Это то, о чем просили, или я что-то пропустил?

Ответ 14

просто замените

file_get_contents

с

$ip = $_SERVER['xxx.xxx.xxx.xxx'];
exec("ping -n 4 $ip 2>&1", $output, $retval);
if ($retval != 0) { 
  echo "no!"; 
} 
else{ 
  echo "yes!"; 
}

Ответ 15

Это может быть намного проще, чем все это. Если вы хотите, чтобы ваша страница загружалась, тогда проверьте наличие или содержимое какой-либо иностранной страницы для запуска другой активности веб-страницы, вы можете сделать это, используя только javascript и php.

yourpage.php

<?php
if (isset($_GET['urlget'])){
  if ($_GET['urlget']!=''){
    $foreignpage= file_get_contents('http://www.foreignpage.html');
    // you could also use curl for more fancy internet queries or if http wrappers aren't active in your php.ini
    // parse $foreignpage for data that indicates your page should proceed
    echo $foreignpage; // or a portion of it as you parsed
    exit();  // this is very important  otherwise you'll get the contents of your own page returned back to you on each call
  }
}
?>

<html>
  mypage html content
  ...

<script>
var stopmelater= setInterval("getforeignurl('?urlget=doesntmatter')", 2000);

function getforeignurl(url){
  var handle= browserspec();
  handle.open('GET', url, false);
  handle.send();
  var returnedPageContents= handle.responseText;
  // parse page contents for what your looking and trigger javascript events accordingly.
  // use handle.open('GET', url, true) to allow javascript to continue executing. must provide a callback function to accept the page contents with handle.onreadystatechange()
}
function browserspec(){
  if (window.XMLHttpRequest){
    return new XMLHttpRequest();
  }else{
    return new ActiveXObject("Microsoft.XMLHTTP");
  }
}

</script>

Это должно сделать это.

Запущенный javascript должен включать clearInterval (stopmelater)

Сообщите мне, если это сработает для вас

Джерри

Ответ 16

Вы можете попробовать использовать PHP на своей веб-странице... примерно так:

<html><body>
<form method="post" name="pingform" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<h1>Host to ping:</h1>
<input type="text" name="tgt_host" value='<?php echo $_POST['tgt_host']; ?>'><br>
<input type="submit" name="submit" value="Submit" >
</form></body>
</html>
<?php

$tgt_host = $_POST['tgt_host'];
$output = shell_exec('ping -c 10 '. $tgt_host.');

echo "<html><body style=\"background-color:#0080c0\">
<script type=\"text/javascript\" language=\"javascript\">alert(\"Ping Results: " . $output . ".\");</script>
</body></html>";

?>

Это не проверено, поэтому у него могут быть опечатки и т.д.... но я уверен, что это сработает. Также может быть улучшено...