views:

24

answers:

1

As part of a diagnostics page I would like to have the user be able to run a "ping", ie an ordinary shell command to send ICMP_ECHO_REQUSTs to a certain IP and display the resuls dynamically in a div in the browser.

The backend is Ruby/Rails.

I'm past running the command on the server side and reading the output from the ping command.

And I've been building web pages that periodically calls back to the server to update som parts of the page dynamically.

But in this case there are three challenges:

  • be able to have the ajax call back to an uri/url to find the process that runs the ping command
  • ideally be able to update the page when the ping command returns a new line of data
  • Optionally be able to "break" the ping. With ping I can of course just set the option to only send x pings and then exit and thus eliminating the need to stop the process. But I also have another tool that would be next, a log viewer, and that tool does not stop by itself after a certain number of lines but continue forever if not interrupted, ie with Control-C.

Do I set up a memcache to rendez-vous with the process running ping or is there a simpler way?

I searched a lot thinking this should be a problem common enough to have a rails plugin just magically implementing whats needed but I didn't find much at all.

Any suggestions or pointers?

A: 

From what it sounds, you only need the ping when the page is loaded and people are watching it. If that is the case, I think you can avoid a backend process.

I would think that an ajax call to a controller action that pings and then outputs the response. You could control the frequency, start, stop through javascript on the page and update a specific div or other page object with the response.

this example uses ruby ping library which only returns true. If you need more functionality there are other libraries available (e.g. net-ping).

In your controller

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

And then in your javascript (I am using jQuery, but you could use prototype/scriptaculous or you favorite JS flavor):

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

From there you can use a setTimeout command to run it every 5 seconds or however often you would like to generate the ping.

If you need the ping going on all the time, you might want to look at some backend job processors like resqueue that would update a database table with the ping results, or a memcached store that you then poll using a similar method as above from the page.

Geoff Lanotte
Aha, OK, thanks! But it was not really what I was looking for and I realize I wasn't clear in my question.I want the ping command to run for some time, 10-20 s, and the web page update an element as new output lines are produced by the ping.The output looks like:PING 192.48.96.9 (192.48.96.9) 56(84) bytes of data.64 bytes from 192.48.96.9: icmp_seq=1 ttl=236 time=123 ms64 bytes from 192.48.96.9: icmp_seq=2 ttl=236 time=123 ms...with one line appearing every second.
Thomas Holmström