【问题标题】:How to show ping output dynamically in a web page?如何在网页中动态显示 ping 输出?
【发布时间】:2011-03-13 18:38:07
【问题描述】:

作为诊断页面的一部分,我希望用户能够运行“ping”,即普通的 shell 命令将 ICMP_ECHO_REQUST 发送到某个 IP 并在浏览器的 div 中动态显示结果。

后端是 Ruby/Rails。

我已经在服务器端运行命令并读取 ping 命令的输出。

我一直在构建网页,这些网页会定期回调服务器以动态更新页面的某些部分。

但在这种情况下存在三个挑战:

  • 能够让 ajax 回调到 uri/url 以找到运行 ping 命令的进程
  • 理想情况下能够在 ping 命令返回新行数据时更新页面
  • 可以选择“中断” ping。使用 ping,我当然可以将选项设置为仅发送 x ping,然后退出,从而无需停止进程。但是我还有另一个工具,即日志查看器,该工具不会在一定数量的行之后自行停止,而是会在不中断的情况下永远持续下去,即使用 Control-C。

我是否设置了一个内存缓存来与运行 ping 的进程会合,还是有更简单的方法?

我进行了很多搜索,认为这应该是一个足够普遍的问题,以至于有一个 rails 插件可以神奇地实现所需的东西,但我根本没有找到太多。

有什么建议或指点吗?

【问题讨论】:

  • 它就像一个带有 ping 的聊天应用程序。您可能需要使用 Comet 进行挑战 #2。

标签: ruby-on-rails ajax shell dynamic command


【解决方案1】:

如果我理解正确,您想要的通常是在客户端从 Web 服务器接收一些信息,而客户端不知道该信息何时传入,即 将信息从 Web 服务器推送到客户端.有几种方法可以做到这一点,它们都有一些缺点:

  • HTTP 推送 - 需要保持活动连接和服务器保持以分块方式发送信息,每次都宣布下一个块传入,并且在准备好之前不发送。通常这个“chucked 流”要么在 XMLHttpRequest 对象中接收,要么在隐藏的 iframe 中接收,尽管如果需要(如您的情况),也可以按原样显示给用户。
  • 轮询 - 客户端只是询问服务器是否有定期传入的内容。令人望而生畏,具有巨大的消息传递延迟和流量消耗,但几乎总是有效。
  • 长轮询 - 轮询和 HTTP 推送的组合 - 即轮询后的第一个回答被延迟,直到它可以回答。
  • Server-sent events (SSE) - 一个几乎被接受的标准,在 Opera 中实施了很长时间,现在许多浏览器都支持它,它的目标是成为 W3C 标准。
  • WebSockets 也是 Google 新提出的标准,允许更复杂的 TCP 连接以及来自 Javascript 的发送/接收功能。它也可以用于 HTTP 推送。
  • 使用非 HTML 方法(即 Flash、Java、Silverlight)获取传入内容。有一些库/现成的模块化 SWF/小程序(例如,BlazeDS)可用于此目的,例如,它们可以将来自给定连接的信息通过隧道传输为目标页面上的 JSON。

所有这些方法确实都包含在“HTTP push”和“comet”的概括性术语中。有大量的文档、教程和现有的解决方案随处可见。例如,对于 RoR,您可以尝试 Juggernautshooting_star,或者选择 minimalistic solutions

最后,我想推荐一篇 Gregor Roth 在 SSE (part 1)WebSockets (part 2) 上的优秀文章,其中给出了详细的解释、示例和使用前景。

【讨论】:

  • OP 对第一个答案的评论也是我个人正在寻找的。更多关于如何同时将 shell 输出输出到网页。
【解决方案2】:

听起来,您只需要在页面加载并且人们正在观看它时进行 ping。如果是这种情况,我认为您可以避免后端进程。

我认为对控制器操作的 ajax 调用会 ping 并输出响应。您可以通过页面上的 javascript 控制频率、启动、停止,并使用响应更新特定的 div 或其他页面对象。

此示例使用仅返回 true 的 ruby​​ ping 库。如果您需要更多功能,可以使用其他库(例如 net-ping)。

在你的控制器中

require 'ping'

def ping
  if Ping.ping_echo(params[:hostname], params[:timeout])
    render :text => "Oh goodie, it pinged successfully"
  else
    render :text => "No go on the pingage"
  end
end

然后在你的 javascript 中(我使用的是 jQuery,但你可以使用原型/scriptaculous 或者你最喜欢的 JS 风格):

function ping_host {
  $.get("/controller/ping", function(data){
    $("#some_div_id").append(data);
  });
}

从那里您可以使用 setTimeout 命令每 5 秒运行一次,或者您希望生成 ping 的频率。

如果您需要一直进行 ping,您可能需要查看一些后端作业处理器,例如 resqueue,它会使用 ping 结果更新数据库表,或者使用类似的方式轮询的 memcached 存储方法同上。

【讨论】:

  • 啊哈,好的,谢谢!但这并不是我真正想要的,我意识到我的问题并不清楚。我希望 ping 命令运行一段时间,10-20 秒,并且网页更新一个元素,因为 ping 生成了新的输出行。输出看起来像:PING 192.48.96.9 (192.48.96.9) 56(84) 字节的数据。来自 192.48.96.9 的 64 个字节:icmp_seq=1 ttl=236 time=123 ms 来自 192.48.96.9 的 64 个字节:icmp_seq=2 ttl=236 time=123 ms ...每秒出现一行。
  • 你有没有找到解决这个问题的方法。
猜你喜欢
  • 2017-08-25
  • 2013-02-09
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
  • 2015-11-16
相关资源
最近更新 更多