是否可以从 Javascript ping 服务器?

IT技术 javascript
2021-02-01 18:49:33

我正在制作一个需要检查远程服务器是否在线的网络应用程序。当我从命令行运行它时,我的页面加载时间长达 60 秒(对于 8 个条目,它将随着更多条目线性扩展)。

我决定走用户端ping的路线。这样,我可以加载页面并让他们在浏览我的内容时等待“服务器在线”数据。

如果有人对上述问题有答案,或者他们知道让我的页面快速加载的解决方案,我将不胜感激。

6个回答

我发现有人通过非常巧妙地使用本机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错误。如果有人可以验证替代解决方案,我会将其作为已接受的答案。

这是我一直在用的。然而,它确实有一个缺陷,那就是“图像”被缓存了。当我最初 ping 一个给定的 IP 时,我得到 304 毫秒 - 但是如果我在没有重新加载页面的情况下第二次 ping 它,我会得到 2 毫秒。如果需要,可以通过"/?cachebreaker="+new Date().getTime();在 img src 的末尾附加 a避免这种情况
2021-03-24 18:49:33
这对我不起作用,已知错误的主机名导致 Ping 请求找不到主机...但由于 onerror 是“好”的,这件事说它响应了
2021-03-25 18:49:33
更多的测试表明这是完全不可靠的。
2021-04-02 18:49:33
@Jonathon 创建的 Ping API 将成功 ping 一切。不存在的站点和随机字符。
2021-04-04 18:49:33
Ping API 实际上总是以 onerror 失败。然而,如果目标 URL 表示一个图像,它会触发 onload,这太棒了!绕过 CORS 检查。
2021-04-05 18:49:33

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
  }

}

无论我为主机选择什么,都会调用 pong()。ping( test.zzzzzzzzz, "77", function(m){ console.log("它花了 "+m+" 毫秒。"); }) 打印出“它花了 67 毫秒。” ping( stackoverflow.com, "80", function(m){ console.log("它花了 "+m+" 毫秒。"); }) 给出了一个 CORS 错误:developer.mozilla.org/en-US/docs/Web/ HTTP/CORS/Errors/... 如果远程计算机在线,我不知道如何检查此代码。
2021-03-13 18:49:33
我喜欢这个棘手的解决方案。必须为 pong 提供一个函数而不是返回一个数字对我来说有点奇怪但可行。
2021-03-22 18:49:33
@Nick:这是异步的东西,所以在方法返回时,onreadystatechange还没有触发。这意味着当状态改变时你需要一个回调来接收。
2021-03-28 18:49:33
@armen:您必须提供一个函数作为 ping() 的第三个参数,该参数的值在函数内称为 pong。
2021-03-29 18:49:33
ping("example.com", "77", function(m){ console.log("It took "+m+" miliseconds."); }) .....示例调用
2021-04-03 18:49:33

你可以试试这个:

ping.html放在有或没有任何内容的服务器上,在 javascript 上做如下相同的操作:

<script>
    function ping(){
       $.ajax({
          url: 'ping.html',
          success: function(result){
             alert('reply');
          },     
          error: function(result){
              alert('timeout/error');
          }
       });
    }
</script>
这更适合跨浏览器。
2021-03-20 18:49:33
我正在 ping 的服务器不是我自己的,所以我没有那个选项。不过谢谢。
2021-03-21 18:49:33
由于 CORS,HEAD 类型请求也将不起作用。使用 Chromium 55 进行测试。例如,收到与 net::CONNECTION_REFUSED 相同的 http 代码 0 错误。
2021-03-28 18:49:33
@dlchambers 不是由于 CORS,而是由于跨域策略。CORS 允许服务器指定来源,并且浏览器必须支持它。所以它更像是一个跨域问题。
2021-03-31 18:49:33

您不能在 javascript 中直接“ping”。可能还有其他几种方式:

  • Ajax
  • 使用带有isReachable的 java 小程序
  • 编写一个服务器端脚本,它 ping 并使用 AJAX 与您的服务器端脚本通信
  • 你也可以在 flash 中 ping (actionscript)
Java 的 isReachable 非常不可靠......但是现在是 2018 年,Java Applet 无论如何已经过时了。
2021-04-07 18:49:33

您无法在浏览器 Javascript 中执行常规 ping,但您可以通过例如从远程服务器加载图像来确定远程服务器是否处于活动状态。如果加载失败 -> 服务器关闭。

您甚至可以使用 onload-event 计算加载时间。这是如何使用 onload 事件示例

不幸的是,我正在 ping 的服务器不是 Web 服务器。他们是游戏服务器。
2021-03-18 18:49:33
然后你必须在服务器端执行 ping - 或者你可以考虑一些轻量级的 http-server。
2021-03-21 18:49:33
您可能会考虑利用命令行ping命令。是工业实力。或者,有各种免费/开源应用程序可以使用各种类型的心跳检查来监控主机是否正在运行。
2021-03-24 18:49:33
您需要同时 ping 服务器。您可以通过选择、线程或进程来实现。对于真正的核心解决方案,您可以使用 Eventmachine。
2021-04-06 18:49:33
您知道进行聚合 ping 的方法吗?这是我的主要减速,在另一个请求开始之前等待一个请求完成。
2021-04-07 18:49:33