9

How can I know, in Xul, if the network is (dis)connected?

--update

Using:

    function observe(aSubject, aTopic, aState) {
        if (aTopic == "network:offline-status-changed") {
            write("STATUS CHANGED!");
        }
    }
    var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
    os.addObserver(observe, "network:offline-status-changed", false);

and the preference:

pref("network.manage-offline-status", true);

it's not working.. There's a bug report here, but I don't think it has something to do with it.

--

Actually I think it's not possible to be notified, as even in Firefox we're never notified, and the user need to manually mark "work offline" if he wants the browser to know that it's offline..

--

Screenshot my of Firefox "about:config" filtering for "offline" string, unfortunately, there no "network.manage-offline-status":

enter image description here

The Student
  • 27,520
  • 68
  • 161
  • 264
  • Have you tried configuring the preferences to use network manager, and seeing whether that makes Firefox go offline automatically? – Neil Mar 02 '11 at 19:47
  • @Neil looks like there's no such property, but I'll you check the behavior with the existing "offline" properties.. (see my screenshot) – The Student Mar 02 '11 at 20:11
  • Actually the name of the preference changed recently, but either way it should default to true. I've since noticed the manageOfflineStatus property on nsIIOService2 which you could also check. – Neil Mar 02 '11 at 20:34
  • @Neil Yes, looks like the answer is in that way.. I found [this code](http://www.google.com/codesearch/p?hl=en#6V-_MuMB1HQ/mozilla-2.0.0.3/mozilla-2.0.0.3/mailnews/extensions/offline-startup/js/offlineStartup.js&q=nsIIOService2%20observe%20lang:javascript&sa=N&cd=1&ct=rc&l=66), but I'm having no success using it's approach.. Like he does `ioService.manageOfflineStatus = false;` I did `ioService.manageOfflineStatus = true;`, but my app is still not able to know if it goes offline.. – The Student Mar 02 '11 at 21:24
  • That looks like the Thunderbird code that ports its old preferences to work with the new nsIIOService2 properties. Not sure that it really relates to your problem. – Neil Mar 02 '11 at 21:26
  • @Neil maybe I should try to make a xpcom component? I'll research about.. – The Student Mar 10 '11 at 16:57
  • Do you have the network manager installed? – Neil Mar 11 '11 at 00:33
  • @Neil yes, I've tried both `network.manage-offline-status` and `manageOfflineStatus`. And I've tried with both `nsIIOService2` and `nsIObserverService`. – The Student Mar 11 '11 at 14:02

3 Answers3

5

You should be able to use navigator.onLine. Here is the help page

https://developer.mozilla.org/en/Online_and_offline_events

navigator.onLine is a property that maintains a true/false value (true for online, false for offline). This property is updated whenever the user switches into "Offline Mode" by selecting the corresponding menu item (File -> Work Offline in Firefox).

Another solution (as commented by @Neil):

Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService)
    .addObserver(myF­unction, "network:offline-status-changed", false);
Wayne
  • 59,728
  • 15
  • 131
  • 126
Amir Raminfar
  • 33,777
  • 7
  • 93
  • 123
  • 2
    This won't tell you if someone yanks the network cord though, will it? – corsiKa Mar 01 '11 at 20:24
  • You know I was thinking about that myself to because even my applications don't always know that the network cable was yanked until they timeout or there isn't a valid ip address. I am afraid I don't have a better answer for you :( – Amir Raminfar Mar 01 '11 at 20:27
  • Maybe I used the wrong phrase, I mean how to know if it "becames" disconnected. As told, if the cable is removed, I need to know. But maybe the only solution is a script to be consulting this property every second.. – The Student Mar 01 '11 at 20:45
  • Yes, looks like the available way is to check the property in a setInterval function, as [this link](http://ejohn.org/blog/offline-events/) (found on your link) says. But, also, I'll wait before marking your answer as correct, as maybe anyone have a better solution.. – The Student Mar 01 '11 at 20:55
  • No, I think the better approach is to add a listener. I believe this is possible with offline events. This is a better approach than polling. – Amir Raminfar Mar 01 '11 at 21:32
  • 2
    There are `network:offline-status-changed` observer notifications for going online and offline. If you also set the `network.manage-offline-status` preference to true (and if your platform supports it) then the offline status will reflect what the OS thinks it is. – Neil Mar 02 '11 at 00:22
  • @Neil great! @Amir Raminfar if you want to complete your answer, the code is `Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService).addObserver(myFunction, "network:offline-status-changed", false);;` – The Student Mar 02 '11 at 13:11
  • @Neil actually, you comment should be an answer. – The Student Mar 02 '11 at 13:17
  • @Tom - I updated my answer. What browser are you testing this in? ff4 or 3? – Amir Raminfar Mar 02 '11 at 14:53
  • @Amir Raminfar: FF3 (Gecko 1.9.2.13) – The Student Mar 02 '11 at 17:54
  • Can you try 4 beta just out of curiosity? I recall this being mentioned in their release notes. – Amir Raminfar Mar 02 '11 at 18:12
  • @Amir Raminfar: Actually, it's not Firefox, it's an Xul based desktop application. Unfortunately, I'll not be able to test it in Gecko 2, as I would need the help of many people in the lab here to compile the Gecko 2 to our embedded system. If there's no solution, I'll pass it to someone to create some C code for listen to the network port directly, or something like that.. – The Student Mar 02 '11 at 18:20
  • @Tom Brito I think he means you should try writing test Firefox extensions just to see whether you can get it to respond the way the documentation suggests, and if that works it might help you troubleshoot your embedded system. – Neil Mar 11 '11 at 23:27
  • Maybe it would work in FF4, but we did the XPCom as other solutions were taking too long.. anyway, thanks! =) – The Student Mar 29 '11 at 18:28
2

The best way I found is to use the following javascript code, that behaves like a ping, and make the test with some big websites, and assume that if none of them answers, so the network must be disconnected.

var ping = {};
ping = {
    img:null,
    imgPreload:null,
    timer:null,
    init:function() {
        var sess = new Date();
        var nocache = sess.getTime();
        var imguri = ping.img+"?time="+nocache;
        var ping.imgPreload = new Image();
        ping.imgPreload.onload = function() {
            clearTimeout(ping.timer);
            ping.timer = null;
            alert("Domain is available");
        };
        ping.imgPreload.src = imguri;
        ping.timer = setTimeout("ping.fail_to_ping()",60000);
    },
    fail_to_ping:function() {
        clearTimeout(ping.timer);
        ping.timer = null;
        ping.imgPreload = null;
        alert("Ping to domain failed!");
    }
};

(from http://crynobone.com/ci/index.php/archive/view/852)

--update

But, as it's not a reliable solution (as you can't rely that the image will be in the website forever), the best solution might be to develop a new XPCom component.

The Student
  • 27,520
  • 68
  • 161
  • 264
  • Ok, this will work only for image urls, I need something like that for a html page.. – The Student Mar 10 '11 at 14:31
  • @Tom: Well this solutions is actually quite neat. The image thing is just to check if the connection is there. After that you can load your html page, as you have confirmed the connection. – Tokimon Mar 21 '11 at 00:47
  • @Tokimon it's not a reliable solution, I can't rely on any image on the web to be always there. – The Student Mar 21 '11 at 12:36
  • @Tom: True... AJAX might be of help. You just need to connect to one you own pages to test... – Tokimon Mar 25 '11 at 13:10
  • @Tokimon you mean one of my pages of the application itself, or of my website? If the second, I can't rely my website will be always up. If the first, it will not use the internet to connect to my own app.. – The Student Mar 29 '11 at 13:09
  • @Tom: I was thinking if images have been disabled. it would give a wrong feedback. it might say the connection is offline, even though it is online. – Tokimon Apr 05 '11 at 22:50
0

Eh... as per HTML5 (read echmascript 5), the on-/offline events are available.

See it here at Mozilla Hacks

Edit 20/4/2011:
I just encountered an update for this answer, when i was watching a podcast from MS MIX11:
http://channel9.msdn.com/Events/MIX/MIX11/HTM14 around time 43:36, the lecturer is actually talking about the window.navigator.onLine property, where he uses it for detecting if the browser (and the computer) is online. Then he uses the online event to do something when he gets online again.

This method is only available in modern browsers, however. So IE 8 and below have to poll for the connection.

Tokimon
  • 4,072
  • 1
  • 20
  • 26
  • Acording to [this page](http://help.dottoro.com/ljnasgpu.php) this event is supported in IE 8+ and FF 3+ – Tokimon Mar 11 '11 at 12:20
  • Good to know! Unfornately, the example on the mozilla page is always showing "ONLINE" to me. Even if I open the file with the physical cable unplugged. – The Student Mar 11 '11 at 13:20
  • Also, the html5 tag with google chrome don't work. It says you have to click on "File->Offline" to switch, but such option is not available on Google Chrome, and it probably will not recognize a lost of connection. Sad, looked like a good solution.. – The Student Mar 11 '11 at 13:47