Does anyone know a way to test to see if the computer is connected to
the internet in Ruby?
I wrote a Ruby program with WWW::Mechanize, but it completely hangs Ruby
when my internet is turned off. Because Ruby does not use system
threading, there is no way to check for a timeout when WWW::Mechanizer
freezes due to not having an internet connection.
Does anyone know a way to test to see if the computer is connected to
the internet in Ruby?
I wrote a Ruby program with WWW::Mechanize, but it completely hangs Ruby
when my internet is turned off. Because Ruby does not use system
threading, there is no way to check for a timeout when WWW::Mechanizer
freezes due to not having an internet connection.
require 'ping'
Ping.pingecho("google.com",10,80) # --> true or false
loop do
break if system(“ping google.com”)
sleep 1
end
puts “Internet working!”
Cory C. wrote:
Does anyone know a way to test to see if the computer is connected to
the internet in Ruby?
I wrote a Ruby program with WWW::Mechanize, but it completely hangs Ruby
when my internet is turned off. Because Ruby does not use system
threading, there is no way to check for a timeout when WWW::Mechanizer
freezes due to not having an internet connection.
require ‘resolv-replace’
might help, or google for ruby asynchronous dns
I know rev has one, and also there is a package for eventmachine that
does it.
The problem is that when it does DNS lookup it hangs forever (I’d
imagine) waiting for a response.
This might help it.
loop do
break if system(“ping 64.233.187.99”)
sleep 1
end
puts “Internet working!”
The ruby-dbus package is still being developed. Most importantly, it is
not available in any deb package list. This means I cannot write code
that would be very portable with this.
This describes nearly every Ruby library in existence.
I was referring to the fact that ruby-dbus is still in a pre-beta
release form.
sudo gem install dbus
Are you suggesting that I should just write a C function to handle
internet detection? That seems like a clean answer, but C in Ruby is
something I still have yet to learn. Seems like a good time to start.
This describes nearly every Ruby library in existence.
Most importantly, it is
not available in any deb package list. This means I cannot write code
that would be very portable with this.
sudo gem install dbus
If you are depending on only libraries that are deb-packaged, your
code will neither be portable (to non-deb linuxen) nor will you be
able to take advantage of many Ruby libraries (since very few are deb
packaged).
The ruby-dbus package is still being developed. Most importantly, it is
not available in any deb package list. This means I cannot write code
that would be very portable with this.
Any other suggestions?
Grab the gem onto your box, after check the license of the gem, copy
the core code you need into your projects lib/ folder in it’s own file
then use it as part of your own package.
That way as well you can help fix / improve / finalize the gem and deb
package your own code all you want
Well after all of that, I can’t compile the dbus gem unless I download
and compile the newest version of the real dbus (because the deb is
still out of date). Interfering with my deb’s is not something I like
doing because of updates, so I guess I’ll just have to wait.
Maybe Hardy Heron will solve my problems.
If Ruby just had system threading this would not even be an issue. Once
again, I guess I will just have to wait.
On Fri, Mar 21, 2008 at 8:04 AM, Lionel B. < [email protected]> wrote:
If Ruby just had system threading this would not even be an issue.
Lionel
I’d just like to add to this thread that regardless of locking issues,
pinging may not be the definitive test for whether or not you have
internet
connectivity. Just that you cannot ping doesn’t mean you can’t build TCP
circuits to a port 80, and conversely just being able to ping doesn’t
mean
you’re not behind some evilly or otherwise misconfigured firewall that
will
drop all you traffic to destination port 80. In short, you may be
getting
false positives as well as false negatives, and testing for internet
connectivity should involve testing what you actually intend to do. If
you
application needs to fetch something via TCP from destination port 80,
do
that.
Well after all of that, I can’t compile the dbus gem unless I download
and compile the newest version of the real dbus (because the deb is
still out of date). Interfering with my deb’s is not something I like
doing because of updates, so I guess I’ll just have to wait.
Maybe Hardy Heron will solve my problems.
If Ruby just had system threading this would not even be an issue.
Your problem isn’t clear enough for a good advice : do you need an
answer to the “Is net available?” in finite time or do you want to
continue processing while you wait for the answer?
If you want to continue processing, your only need is a non-blocking
communication channel with another process/thread. The usual solution is
to use an event loop, in this case something like popen with the ping
program or whatever you need would give you the asynchronous behaviour
you need.
I’ve a strong opinion on threads (built on several projects where
avoiding deadlocks between them took most of my time instead of adding
functionnalities): if you can avoid them (don’t need the power of
several CPU cores and even then multi-process is an option), go for the
event-loop. In Ruby’s case, where multi-threading doesn’t use multiple
cores, I only use threads in the simplest conditions (fetching several
URIs in parallel with no interlocking for example).
If you only need an answer in finite time, see man ping on your OS.
The code is not completely wrong but in real case scenarios is
impractical.
First off you need to issue a command that will send 1 ping request (or
at least a finite number), otherwise
the process will never end. So you should use something like ‘ping -c 1
some.host’.
Second, you need to somehow handle kernel#system output which is not easy. Either you have to redirect the output to /dev/null in which
scenario
you might better of using bash instead of ruby all together, or use a
gem to handle everything for you and return just true/false:
#!/usr/bin/env ruby
require ‘net/ping’
def up?(host)
check = Net::Ping::TCP.new(host)
check.ping
end
Generally speaking though, it’s better to use other approaches like
backticks or open3[1] which are considered more ‘secure’ and offer more
options, although kinda hard to grasp at first.