Detect internet connectivity

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

stam
Posts: 2758
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Detect internet connectivity

Post by stam » Sat Sep 09, 2023 2:11 pm

trevix wrote:
Sat Sep 09, 2023 1:53 pm
What I mean to say is that the "put URL", the first time after disconnection, will wait quite a long time.
When run again (cached?), the script will then run fine, reporting disconnected.
Hi Trevix, again I'm not able to replicate this. I can run the script and get the IP, disconnect wifi and the immediately on next run it reports failure and reattempts 10 times - if wifi is switched on during the 10 re-attempts it immediately reports success.

I should clarify I'm not running this in an app of any kind - I just added the handler to the stack I'm working on and am running it with the msgBox. But I'm not seeing any caching, delays or anything similar.

Hey ho...

-- EDIT: I should also clarify I'm running this on MacOSX 13.5.1 Ventura, on an M2 Pro MBP using LiveCode 10 DP6...

trevix
Posts: 970
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Detect internet connectivity

Post by trevix » Sat Sep 09, 2023 2:51 pm

I am on OSX Monterey, LC 10 DP6

This is my test connection stack.
Just open it with LC.
Your code is in Button 6.
recipe:
connect you mac to wifi
click on btn 6
expected result: the external IP
observed result: the external IP

Now turn off wifi.
click on btn 6 (and be patient)
expected result: no connection after 10 seconds (or whatever has been set with the send)
observed result: no connection after 30 seconds or more
Let me know if it works the same for you (if not could be because of the different OSX version...)
Attachments
CheckMyInternet.livecode.zip
(44.16 KiB) Downloaded 60 times
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4027
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Detect internet connectivity

Post by bn » Sat Sep 09, 2023 10:26 pm

Hi Trevix,

I was amazed by the difference between Stam's original script and your implementation of it in button 6 of your stack.

The only difference I could spot is that Stam did not use a variable but addressed the URL directly.

If you change your script of button 6 to

Code: Select all

command putExternalIP
   local tJSON, tArray, tURL
   MyLog "Put url"
   -- put "https://ipv4.ipleak.net/json/" into tURL
   -- put URL tURL into tJSON // force ipv4 with ipleak.net
   put URL ("https://ipv4.ipleak.net/json/") into tJSON // force ipv4 with ipleak.net
   -- more code
It is as fast as Stam's original script. I have no idea why this should be the case and know nothing about IP addresses etc.

KInd regards
Bernd

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4027
Joined: Sun Jan 07, 2007 9:12 pm
Location: Bochum, Germany

Re: Detect internet connectivity

Post by bn » Sat Sep 09, 2023 10:50 pm

Hi Trevix,

If you block the "socket" stuff in your preOpenStack handler

Code: Select all

   --   repeat for each line tLine in the opensockets
   --      put item 1 of tLine into tFirst
   --      if  tFirst = "192" OR tFirst = "172" then --172 is for hotspot
   --         set the itemdelimiter to ":"
   --         put item 1 of tLine into gRemoteDebugIP -- only IP, no port so that in loop we can clear all sockets
   --      end if
   --   end repeat
   tsNetInit
   --breakpoint
end Preopenstack
your original script for button 6 works as fast as Stam's version.

Again no idea why this should be...

Kind regards
Bernd

stam
Posts: 2758
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Detect internet connectivity

Post by stam » Sun Sep 10, 2023 2:17 am

Hi Trevix and Bernd

Actually Trevix is correct.
I don't understand why - when I was calling the handler in my stack from the messageBox it worked flawlessly and I had no cacheing issues, but this doesn't seem to be the case when called from a stack.

When calling the code from a stack (while I checked Trevix's stack, I made a new one to ensure not issues with other code), the first time the button is pressed with the internet off, there is a 30+ second delay. Every subsequent press is just a few milliseconds and works as expected. Not only that, but when I kept trying it eventually crashed my IDE several times. I suspect there some kind of weird bug there, possibly a memory leak of some kind? Should this be reported?

I didn't see any change commenting out the openSockets-related code in preOpenStack, this issue remained. I comment on that code below.

Anyway, I was able to work around the issue using networkInterfaces
When connected to my wifi, this returned

Code: Select all

127.0.0.1
192.168.1.65
but with the internet switched off, only the loopback IP is available:

Code: Select all

127.0.0.1
so the obvious is to use this to check if internet connection: if networkInterfaces = "127.0.0.1" is true, there is no internet connection.
I updated my code also to fit in with Trevix's myLog handler (effectively does the same as my ipDelegate handler, no point in having both) and added a global to log the elapsed time.
What I don't know is if this will work on Android - may Trevix has already tried this and found networkInterfaces doesn't? (it is supposed to)

Anyway the updated code is in the stack script:

Code: Select all

global gStart
local sCurrentTry

command putExternalIP
    local tJSON, tArray
    if the networkInterfaces = "127.0.0.1" then // only  loopback interface available; if internet connection should be >1 lines
        add 1 to sCurrentTry
        if sCurrentTry > field "fldCounter" then 
            myLog "Sorry: no internet after" && field "fldCounter" && "attempts"
            put 0 into sCurrentTry
            MyLog "Elapsed:" && the milliseconds - gStart && "ms"
        else
            send "putExternalIP" to me in 500 milliseconds
            MyLog "No internet connection - attempt " & sCurrentTry && "of" && fld "fldCounter"
        end if
    else
        put JSONToArray(URL ("https://ipv4.ipleak.net/json/" )) into tArray
        myLog tArray["ip"]
        MyLog "Elapsed:" && the milliseconds - gStart && "ms"
        put 0 into sCurrentTry
    end if
end putExternalIP

command MyLog pText
    put pText & cr after fld "MyLog"
end MyLog
and the button code:

Code: Select all

global gStart

command Mouseup
    put the milliseconds into gStart
    put empty into fld "MyLog"
    putExternalIP
end Mouseup
Out of habit I move the preOpenStack into the card script because I think it's supposed to reside in the script of card 1
I don't really understand the openSockets-related code... if you want the local IP then I would use networkInterfaces instead... on my system the openSockets() just returns a 5-digit number (eg: 49729) so the code below that just won't work... but maybe that's an Android thing?
As it is, I don't understand it (at least on desktop...).

My new stack attached below.

--- EDIT --- I just noticed the tJSON variable is superfluous - I had added this because calling JSONToArray with a non-JSON string (eg empty) caused an error, but this is no longer needed as JSONToArray is only called if there is a network connection and is reduced to a single line.
Attachments
CheckExternalIP.livecode.zip
(40.04 KiB) Downloaded 54 times

trevix
Posts: 970
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Detect internet connectivity

Post by trevix » Sun Sep 10, 2023 10:27 am

My knowledge on networks is limited so you will excuse me if I write incorrect explanations.
What I don't know is if this will work on Android - may Trevix has already tried this and found networkInterfaces doesn't? (it is supposed to)
networkInterfaces works fine on Android, but this funcion is useful, for me, only to find out the local network IP for local socket comm, not to confirm internet connection and get the external IP.
If networkInterfaces reports:
127.0.0.1
192.168.1.65
this does not mean for sure that you are connected to internet and 192.168.1.65 is not your external IP (the IP used to reach your router from outside your local network).
NetworkInterfaces also is not so easy to use when your mobile device, connected to wifi and data cell, returns:
- 127...
- your wifi IP
- your Data cell IP
- and, if you enable hotspot, another ip.
And I don't think there is a meaningful list order.
But this thing on local IP is another story. Here we are talking of external IP and internet connection (which must somehow be confirmed by a return from the web).

About the PreOpenstack code.
Sorry, this is a leftover for my use and I should have removed from the test stack since, to search for a connection, is not useful at all.
In case you ask, I use i on launch when remote debugging.
Since the remote debugger relay on wifi, I need to exclude that IP on socket connections in my standalone.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

trevix
Posts: 970
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Detect internet connectivity

Post by trevix » Sun Sep 10, 2023 10:34 am

this does not mean for sure that you are connected to internet
As a proof, if I remove the SIM card from my portable battery powered router, I can still connect to it, from a mobile device, using WiFi. NetworksInterfaces return the the local IP but, obviously, it is not connected to the web.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

stam
Posts: 2758
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Detect internet connectivity

Post by stam » Sun Sep 10, 2023 12:04 pm

You are of course entirely correct - presence of a local IP does not signify internet connectivity necessarily - my mistake (late night coding...)

Going back to my original code:

Code: Select all

local sCurrentTry, sNumberOfTries = 10 // number of attempts to connect to wifi 

command putExternalIP
    local tJSON, tArray
    put URL ("https://ipv4.ipleak.net/json/") into tJSON // force ipv4 with ipleak.net
    if tJSON is empty then
        add 1 to sCurrentTry
        if sCurrentTry > sNumberOfTries then 
            ipDelegate "Sorry - could not connect tot he internet after" && sNumberOfTries && "attempts"
            put 0 into sCurrentTry
        else
            send "putExternalIP" to me in 500 milliseconds
            ipDelegate "No internet connection - attempt " & sCurrentTry && "of" && sNumberOfTries
        end if
    else
        put JSONToArray(tJSON) into tArray 
        ipDelegate tArray["ip"]
        put 0 into sCurrentTry
    end if
end putExternalIP

command ipDelegate pMessage // put the failure message or the ip in the msgBox
    put return & pMessage after msg
end ipDelegate
This is now weirdly not behaving like it was initially either. Before, switching off my wifi caused no delays, but now it does.

Interestingly: If I quit LC IDE altogether, then switch off wifi, and then reopen the stack and call it from the messagbox there is no delay, which suggests there isn't a problem with get URL per se, but it's probably a cache issue.

The delay now only occurs if a) the script is run while connected to Internet, b) Internet is switched off and c) the script is re-run. Running from cold at start up is not affected by delays, which for your purposes may well work as I gather this is the start up check.

There has to be some monkey business going on with the get URL command... or at least the cacheing. In fact the issue is resolved if one uses resetAll (from the internet library) which amongst other things resets the cache, ie:

Code: Select all

command putExternalIP
    local tJSON, tArray
    resetAll  -- fixes the issue on desktop 
    put URL ("https://ipv4.ipleak.net/json/") into tJSON
    ....
The only fly in the ointment is that the documentation states compatibility for macOS/win/linux. But perhaps, like some other interment library handlers, this is built into the engine for iOS/Android and doesn't require the Internet library external.

I've updated my example stack which works for me perfectly on desktop at least - the dependency on local IP addresses has been removed and it basically works because the cache is reset on each run. Well, nearly perfectly - if switching internet back on and running it there is now a ~2 sec delay, I'm guessing because everything internet-wise is reset.
If adding to a standalone you need to include the Internet library - unknown if this works on mobile.

*** EDIT *** Another potential issue for your app:
Dictionary entry on resetAll wrote:...closes all open sockets, which includes any other sockets opened by your application and any sockets in use for other uploads and downloads...
Depending on what your app is doing this may also be a showstopper.
Attachments
CheckExternalIP.livecode.zip
(40.01 KiB) Downloaded 59 times
Last edited by stam on Sun Sep 10, 2023 1:27 pm, edited 1 time in total.

stam
Posts: 2758
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Detect internet connectivity

Post by stam » Sun Sep 10, 2023 12:48 pm

More cache weirdness:
although clearly some kind of cacheing issue and resolved with resetAll, https://ipv4.ipleak.net/json/ never appears in the cachedURLs and neither does the following code ever complete:

Code: Select all

load url  ("https://ipv4.ipleak.net/json/")
wait until URLStatus("https://ipv4.ipleak.net/json/") is "cached"
which means I can't selectively unload https://ipv4.ipleak.net/json/ from the cache and seem to have to rely on resetAll, which may be showstopper for you (or not, I don't know - if this is a startup routine then probably not!).

trevix
Posts: 970
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Detect internet connectivity

Post by trevix » Tue Sep 12, 2023 9:49 am

resetAll, which may be showstopper for you
It is.
In my standalone, beside using the remote debugger, I extensively use socket communications, API to Filemaker server and to Microsoft Azure.
So a "resetAll" is not a solution for me.

In my case also, the code must be blocking (run it all before going on) and your use of the send in time is not.

Just as an info: what I thought was my perfect solution, the use of tsNetGetSync, it is not. Somehow those commands interfere with other part of the standalone where I use tsNet to do FTP and API call to some services. It's a mess.

So, the search for the perfect function is still on.
Being this function (return the external IP and, as such, confirm or not an internet connection) so important in our days, I wonder why no knowledgeful LC programmer is chipping in in this conversation.
Bah...
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

trevix
Posts: 970
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Detect internet connectivity

Post by trevix » Tue Sep 12, 2023 11:15 am

Geee...this thing will never end.

I just found out that the command "tsNetSetTimeouts" acts as a timeout setting also for the put URL command (on desktop at least).
That is:
- disconnect your Mac from any network
- place in your script a tsNetSetTimeouts 5, 7000, 7000, 7000, 30, 1000 before calling the URL to find your IP

Result: not finding any connection to internet, your script will resolve in 7 seconds.

Boh!
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

stam
Posts: 2758
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Detect internet connectivity

Post by stam » Tue Sep 12, 2023 12:25 pm

trevix wrote:
Tue Sep 12, 2023 9:49 am
, I wonder why no knowledgeful LC programmer is chipping in in this conversation.
Bah...
Blocking code presents no difficulty - I already posted an equivalent blocking handler above. But that’s not your issue!

Sounds like your setup is complex and not just a startup check, and that there is no realistic option to resigning your approach (ie re-authenticating with your connected services etc).

Have you emailed support at livecode dot com for help?
If you just want to get your external IP there may be a native function you can hook into for example…

What I don’t understand is the 30 sec delay when internet goes off. Ideally there would be a way to force reloading a URL from the net instantly instead of a cached URL, which I can’t do now because the URL doesn’t appear in cachedURLs.

As you say: “bah” ;)

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”