Можно ли пинговать сервер из Javascript? - PullRequest
139 голосов
/ 26 ноября 2010

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

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

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

Ответы [ 16 ]

122 голосов
/ 14 августа 2012

Я нашел кого-то, кто выполняет это с очень умным использованием нативного объекта 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.Если кто-то может проверить альтернативное решение, я поставлю его в качестве принятого ответа.

17 голосов
/ 20 декабря 2012

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
  }

}

17 голосов
/ 26 ноября 2010

Вы можете попробовать это:

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

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>
12 голосов
/ 26 ноября 2010

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

  • Ajax
  • Использование Java-апплета с isReachable
  • Написание сценария на стороне сервера, который проверяет связь и использует AJAX для связи с вашим сервером.
  • Возможно, вы также сможете пинговать во флэш-памяти (actionscript)
8 голосов
/ 26 ноября 2010

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

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

5 голосов
/ 08 мая 2014

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

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

Это вернет значение true / false, если сервер существует.

Если вы хотите время отклика, сделайте небольшую модификацию:

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);
5 голосов
/ 30 июля 2013

Подключение с помощью веб-сокета ...

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);
}
5 голосов
/ 26 ноября 2010

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

4 голосов
/ 26 ноября 2010

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

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

2 голосов
/ 09 ноября 2015

Здесь есть много сумасшедших ответов, особенно о 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 или что-то еще ...

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