如何在网页中动态显示ping输出?

Tho*_*röm 9 ajax shell command ruby-on-rails dynamic

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

后端是Ruby/Rails.

我已经过去在服务器端运行命令并从ping命令读取输出.

我一直在构建网页,定期回调服务器动态更新页面的部分内容.

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

  • 能够将ajax调用回uri/url以查找运行ping命令的进程
  • 理想情况下,当ping命令返回新的数据行时,能够更新页面
  • 可选择能够"打破"ping.使用ping我当然可以将选项设置为仅发送x ping然后退出,从而消除了停止进程的需要.但是我还有另一个工具,它将是下一个日志查看器,并且该工具在一定数量的行之后不会自行停止,但如果没有被中断则继续,即使用Control-C.

我是否使用运行ping的进程设置了一个memcache来进行渲染,或者是否有更简单的方法?

我搜索了很多想,这应该是一个常见的问题,有一个rails插件只是神奇地实现了所需的东西,但我没有找到太多.

有什么建议或指示?

Gre*_*Cat 7

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

  • HTTP推送 - 需要保持活动连接,服务器保持以分块方式发送信息,每次都宣布下一个块传入,直到准备好才发送.通常这个"chucked stream"要么在XMLHttpRequest对象中接收,要么在隐藏的iframe中接收,尽管如果需要的话(例如你的话)可以将它显示给用户.
  • 轮询 - 客户端只询问服务器是否有定期传入的内容.令人生畏,有巨大的消息传递延迟,这是一个交通拥挤,但几乎总是工作.
  • 长轮询 - 轮询和HTTP推送的组合 - 即轮询后的第一个回答被延迟,直到它将被回答.
  • 服务器发送事件(SSE) - 几乎被接受的标准,在Opera中实现了很长时间,现在许多浏览器都支持它,它的目标是成为W3C标准.
  • WebSockets也是Google新提出的标准,允许更复杂的TCP连接以及Javascript的发送/接收功能.它也可以用于HTTP推送.
  • 使用非HTML方法(即Flash,Java,Silverlight)来获取传入内容.例如,有一些库/现成的模块化SWF/applet(例如,BlazeDS)可用于此目的,它可以将来自给定连接的信息隧道传送到目标页面上作为JSON执行.

所有这些方法确实涵盖了"HTTP推送"和"彗星"等术语.有大量的文档,教程和现有的解决方案.例如,对于RoR,您可以尝试Juggernautshooting_star,或者只选择简约的解决方案.

最后,我想推荐Gregor Roth关于SSE(第1部分)WebSockets(第2 部分)的优秀文章,其中给出了详细的解释,示例和使用前景.


Geo*_*tte 2

听起来,您只需要在页面加载并且人们正在观看时执行 ping 操作。如果是这样的话,我认为你可以避免后端进程。

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

这个例子使用 ruby​​ ping 库,它只返回 true。如果您需要更多功能,可以使用其他库(例如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
Run Code Online (Sandbox Code Playgroud)

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

function ping_host {
  $.get("/controller/ping", function(data){
    $("#some_div_id").append(data);
  });
}
Run Code Online (Sandbox Code Playgroud)

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

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