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

Jellobus
Posts: 317
Joined: Tue Dec 10, 2013 2:53 pm

Detect internet connectivity

Post by Jellobus » Fri Oct 24, 2014 10:28 am

Hi All,

I was wondering how to find out internet connectivity of ios and android based device?

for example, I want to write code like this..

Code: Select all

if there is an internet connection then
   doTheWork
else
  skipTheWork
end if
Please advice and thanks a lot in advance!


Cheers,

Louis

LCNeil
Livecode Staff Member
Livecode Staff Member
Posts: 1223
Joined: Wed Oct 03, 2012 4:07 pm

Re: Detect internet connectivity

Post by LCNeil » Fri Oct 24, 2014 10:55 am

Hi Louis,

You could check the returned data of a PUT URL statement. If its empty, then no connection is available. If it returns data, then a connection is available. e.g.

Code: Select all

put url "http://www.google.com" into tURL
 
  if tURL is empty then
      --skipTheWork
   else
      --doTheWork
   end if
Kind Regards,

Neil Roger
--
LiveCode Support Team ~ http://www.runrev.com
--

phaworth
Posts: 592
Joined: Thu Jun 11, 2009 9:51 pm

Re: Detect internet connectivity

Post by phaworth » Fri Oct 24, 2014 7:25 pm

Here's a function given to me by Phil Davis. The uRIP["Website"] of stack the mainstack" stuff just gets a website URL so you can use any you want there.

Code: Select all

function appIsConnected
   
   local tShellOutput,tResult
   
   switch (the platform)
      case "MacOS"
         put shell("ping -c 1 -t 5" && the uRIP["website"] of stack the mainstack of this stack) into tShellOutput
         put the result into tResult
         break
      case "Win32"
         set the hideConsoleWindows to true
         put shell("ping -n 1 -w 5000" && the uRIP["website"] of stack the mainstack of this stack) into tShellOutput
         put the result into tResult
         break
      case "Linux"
         put shell("ping -c 1 -w 5") && the uRIP["website"] of stack the mainstack of this stack into tShellOutput
         put the result into tResult
         break
      default -- all other OSes
         put param(0) & colon && the platform && "platform not supported" into tResult
         break
      end switch
   
      -- check for connection failure
   if tResult <> empty then
      return false -- failed
   else -- connected, but how well?
      set the itemDel to comma
      switch the platform
         case "Win32"
            get tShellOutput 
            filter it with "*(0% *"
            break
         case "MacOS" 
            repeat for each item tFilter in "* 0% *,* 0.0% *" -- for different OS versons
               get tShellOutput
               filter it with tFilter
               if it <> empty then exit repeat
            end repeat
            break
      end switch
      return (it <> empty)
   end if
end appIsConnected
Pete

Jellobus
Posts: 317
Joined: Tue Dec 10, 2013 2:53 pm

Re: Detect internet connectivity

Post by Jellobus » Tue Oct 28, 2014 9:07 pm

Hi Neil and phaworth,

both scripts work perfectly. Thank you very much!

Cheers,

Louis

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

Re: Detect internet connectivity

Post by trevix » Fri Sep 08, 2023 12:25 am

Another post resumed...
My standalone (iOS and Android) needs to know if the device is connected to internet and to obtain the public IP (not the local IP)
I had a script that was working fine, using "http://ifconfig.me/ip". Then, on the last update, I realised that the website started to respond with the IPv6 instead of the IPV4, so I decided to use a different approach.

I uploaded a file to a web site with the following code that, when reached, supply a clean public IP.

Code: Select all

<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo 'User IP Address_'.$_SERVER['REMOTE_ADDR']; ?>
 </body>
</html>
This is the LC script I am using:

Code: Select all

local sMyIP
on mouseUp pButtonNumber
     set the visible of image "LoadingSpinner.gif" to true
     put empty into sMyIP
     load URL "https://www.referi.it/returnip.php" with message "CheckGetMyIPreceived"
     repeat with U = 1 to 15
          if sMyIP is not empty then
               exit repeat
          end if
          wait 500 milliseconds with messages
     end repeat
     set the visible of image "LoadingSpinner.gif" to false
     if sMyIP is not empty then
          put lineOffset("User IP Address", sMyIP ) into tLineNum
          set the itemdelimiter to "_"
          answer word 1 of item 2 of line tLineNum of sMyIP 
     else
          answer "no Internet"
     end if
end mouseUp

command CheckGetMyIPreceived  pURL, pURLStatus
    if pURLStatus is "cached" then
         put URL pURL into sMyIP
    else
         put empty into sMyIP
    end if
    unload url pURL
end CheckGetMyIPreceived
I need the standalone to be able to handle situations where the WiFi goes off or the SSID changes (the device connects to a different wifi).
Consider also:
  • In my tests, I always gave enough time, after test disabling/enabling the wifi or connecting the device to a different router, before running the LC script.
  • The script URL download should be "blocking", since the code after that depends on a positive wifi connection.
  • I think that 6-10 seconds are a reasonable time after wich the script should decide that there is not a internet connection. More than that may have the user think that the app is hanging...
  • I could not find any ready made way to change the timeout of the connection, since socketTimeOut apply to sockets only and tsNetSetTimeouts does not apply either
  • For obvious reasons, the response behaviour on OSX, iOS and Android should be as similar as possible.
These are my findings:
--OSX 12.6.8
--change of SSID: erratic behaviour : first time reports no connection. Second time reports the new IP after a while.
--Wifi > nowifi as from loop, it takes 15x500 milliseconds to report no internet. Usefull if wifi strenght is low??
--nowifi >wifi: Ok

--iOS 16
--change of SSID: erratic behaviour : first time reports no connection. Second time reports the new IP after a while.
--Wifi > nowifi as from loop, it takes 15x500 milliseconds to report no internet. Usefull if wifi strenght is low??
--nowifi >wifi: Ok

--ANDROID 13
--change of SSID: as from loop, it takes 15x500 milliseconds to report no internet. Usefull if wifi strenght is low??
--Wifi > nowifi and nowifi >wifi works fine

So apparently everything works fine on Android, but not so much on OSX and iOS, which share a similar behaviour.
Any suggestions on this?
(I have tested other solutions but I will keep them for later on, since the above was the overall best one)
Regards
Trevix
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Detect internet connectivity

Post by stam » Fri Sep 08, 2023 8:15 am

A related post may be of help - gives you both public IP and geolocation: https://forums.livecode.com/viewtopic.p ... 46#p225044

And obviously if the return value is empty then no internet connectivity…

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

Re: Detect internet connectivity

Post by trevix » Fri Sep 08, 2023 11:10 am

If you refer to this code:

Code: Select all

on mouseUp
    put "" into  fld "TheAnswer"
    tsNetInit
    tsNetSetTimeouts 5,5000, 5000, 5000, 0, 0
    put "https://api.ipify.org?format=json" into tGetString
    put tsNetGetSync(tGetString, tHeaders, tRecvHeaders, tResult, tBytes) into tTheAnswer
    tsNetClose
    put tTheAnswer into fld "TheAnswer"
end mouseUp
It works very well on iOS and OSX.

On Android it works only the first time it is run (if the device is connected). You have to restart the standalone, in order to get again the IP of the connected device.
Any following mouseUp returns empty (no connection).

I have a feeling that the problem may be related to tsNetSetTimeouts, which is alway been to me a little difficult to figure it out, or to the tsNetClose.
Any suggestion?
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1212
Joined: Thu Apr 11, 2013 11:27 am

Re: Detect internet connectivity

Post by LCMark » Fri Sep 08, 2023 12:01 pm

@trevix: I suspect it will be the tsNetClose - you only need to call Init on app startup and close on shutdown (although the latter probably isn't necessary). If you include tsNet in the inclusions in your standalone settings, then tsNet will be init'd on startup anyway I believe as it will also install the libUrl driver (so url syntax uses tsNet rather than the liburl script library socket-based impl).

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

Re: Detect internet connectivity

Post by trevix » Fri Sep 08, 2023 3:44 pm

1)
You stand correct, Mark.
I removed both the tsNetInit and the tsNetClose and now it works super on Android.
BUT on OSX and iOS, after changing the SSID, on the first run it returns no connection (I guess is cached). Only on a second run of the script it returns the new IP.

So (sigh) I modified the script like this:

Code: Select all

function CheckConnection
 local tAnswer,tArray,tHeaders, tRecvHeaders, tResult, tBytes
     if the platform <>  "Android" then tsNetInit 
     tsNetSetTimeouts 5,7000, 7000, 7000, 0, 0
     put "https://api.ipify.org?format=json" into tGetString
     put tsNetGetSync(tGetString, tHeaders, tRecvHeaders, tResult, tBytes) into tAnswer
     if the platform <>  "Android" then tsNetClose
     if tAnswer is not empty then
          put JSONToArray(tAnswer) into tArray
     end if
     return tArray["IP"]
end CheckConnection
This thing could be a problem though, since I have other different tsNet operations elsewhere in the standalone.
As I understand tsNetClose disable the tsNet external. Should I then tsNetInit and tsNetClose each script running a TsNet something?
I guess that tsNetCloseConn does not apply to tsNetGetSync, since i don't know where to get the specific pConnectionID...

2)
Since I use different timeouts in the standalone, I noticed that this doesn't work, trowing an error on the second line:

Code: Select all

put tsNetGetTimeouts() into tOldTimeouts
...
tsNetSetTimeouts  tOldTimeouts
The only thing that seems to work is

Code: Select all

put item 1 of tOldTimeouts into tDnsCacheTimeout
put item 2 of tOldTimeouts into tRequestTimeoutMS
....
--and then
tsNetSetTimeouts tDnsCacheTimeout, tRequestTimeoutMS, ...
I really appreciate help in this never ending problem.
Trevix
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Detect internet connectivity

Post by stam » Sat Sep 09, 2023 2:47 am

As far as I can tell you're trying to get your external IP?
More than likely I have not understood your requirements - and I'm sorry if I'm wasting your time if that's the case, but on the off-chance I have (I'm extremely sleep-deprived at this point...), why not use the free https://ipleak.net API to get your external IP?
For ipv4 addresses you'd just need to 'get' the URL https://ipv4.ipleak.net/json/
What is the benefit of using TSNet?

Obviously I can't replicate your mobile app, but thought I'd just test this in the IDE. If no IP address the code below tries 10 times at 500 ms intervals iterating each attempt in the msgBox and then reports failure or it puts the ipv4 ip address there instead.
Just for the purpose of putting each of the 10 attempts in the msgBox it delegates the 'putting' into a 2nd command ipDelegate - but of course in an app you would use this differently and this is only really needed if you do 'send it time' to not block the interface.

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 -- JSONToArray chokes if no internet, so only if JSON received. Could this have been the cause of your instabilities?
        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 works nicely in the IDE (switching wifi off/on, switching SSIDs etc) and I can't see why the principle wouldn't work just as well on mobile, but I don't do mobile so can only speculate...

HTH
Stam

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

Re: Detect internet connectivity

Post by trevix » Sat Sep 09, 2023 9:50 am

Thanks. You got it but there is more.

My requirements:
  • being a published App, I must use a URL that I am sure will work forever (sigh). As I wrote before, I was using "http://ifconfig.me/ip" but now it returns the IPV6 (don't know why). But let us assume that your suggested URL will work consistently for a few year.
  • I need a blocking script (synchronous, that returns the external IP) because on launch the standalone acts according to "no internet" or "ok Internet".
  • This blocking script should last no more then 6- 10 seconds before deciding that there is no connection, otherwise the user may decide that the App is stuck :shock:
  • The "put URL" is a blocking command and there is no way, that I know, to decide its timeout in LC. You can test this problem, using your script on the IDE (OSX at least): If you go from wifi enabled to wifi disabled, before reaching the "send" loop your script will stop on the line "put URL" for more then 20 seconds. This, for me, doesn't fit.
  • This is the reason for the tsNetGetSyn, that is synchronous and allows me, using tsNetSetTimeouts, to decide how much should last a search for a faulty connection.
I think I will stick with that, for the moment, waiting for someone to fill up to me the scarce informations available on the dictionary about tsNetInit:
1) why it works differently on iOS and Android installs? (see my last script).
2) Should I always run tsNetInit at launch only? But then how do I clear the cache so that a change of SSID is always reported on the first run of the script?
Trevix
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Detect internet connectivity SOLVED (?)

Post by trevix » Sat Sep 09, 2023 11:04 am

I found the solution for my script, sending a "no_reuse" = true" with the tsNetGetSync.
Now this script works very fast on iOS, Android and OSX, reporting "no internet" or the external IP.

If you find something that, according to you, does not fit or can be a problem in the log run, PLEASE do your objections.

Code: Select all

On PreOpenstack
   tsNetInit --always init the library. In some case this is not needed but doesn't harm.
end Preopenstack

on mouseUp
     local tMyIP
     put CheckConnection() into tMyIP
     put tMyIP into tTest
     replace "." with "" in tTest
     if tTest is a number then
          answer tMyIP
     else
          answer "no internet"
     end if
end mouseUp

function CheckConnection
     local tAnswer,tArray,tHeaders, tRecvHeaders, tResult, tBytes
     set the visible of image "LoadingSpinner.gif"  of card "cdWelcome" to true --my wait spinner
     put tsNetGetTimeouts() into tOldTimeouts --save old timeout
     tsNetSetTimeouts 5,7000, 7000, 7000, 0, 0 --max 7 seconds wait, if no connection
     put "https://api.ipify.org?format=json" into tGetString
     put true into pSettings["no_reuse"] --this clear the cache??
     put tsNetGetSync(tGetString, tHeaders, tRecvHeaders, tResult, tBytes, pSettings) into tAnswer
     tsNetSetTimeouts item 1 of tOldTimeouts, item 2 of tOldTimeouts, item 3 of tOldTimeouts, item 4 of tOldTimeouts, item 5 of tOldTimeouts, item 6 of tOldTimeouts
     if tAnswer is not empty then
          put JSONToArray(tAnswer) into tArray --mergJson extension must be enabled on mobile
     end if
     set the visible of image "LoadingSpinner.gif" of card "cdWelcome" to false
     return tArray["IP"]
end CheckConnection
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Detect internet connectivity

Post by stam » Sat Sep 09, 2023 1:39 pm

trevix wrote:
Sat Sep 09, 2023 9:50 am
But let us assume that your suggested URL will work consistently for a few year.
it will - it's an open source driven VPN provider aiming to promote net neutrality - been around for a while and will continue to be (well as a far anything will I suppose)
trevix wrote:
Sat Sep 09, 2023 9:50 am
  • The "put URL" is a blocking command and there is no way, that I know, to decide its timeout in LC. You can test this problem, using your script on the IDE (OSX at least): If you go from wifi enabled to wifi disabled, before reaching the "send" loop your script will stop on the line "put URL" for more then 20 seconds. This, for me, doesn't fit.
I'm not sure how to replicate your 20 sec delay... or even understand your testing proposition... the steps in the script are:
1. test for internet
2. if no internet then use 'send' to keep trying 10 times (keeping track of number of attempts)
3. if internet return ip

with the flow of the script, it will not react to wifi being disabled after the first line of the script, as the script forks at the very first line of the script around there either being internet or not.

The 'send' you propose causes the problem is ONLY sent if there is not internet at the very first line of the script.... and starting with WiFi disabled definitely produces NO delay for me... as switching wifi on between attempts produces no delay either.

Or maybe I'm just being slow after being on-call 3 weeks out of the last 4...
Could you clarify your point a bit for me please?

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

Re: Detect internet connectivity

Post by trevix » Sat Sep 09, 2023 1:53 pm

Let's see...
connect your Mac to internet wifi (disconnect ethernet if connected)
in the script:

Code: Select all

line 3 "put url" 
line 4 "if Json is empty" and following will run fine, reporting immediately the IP
turn off wifi on Mac
in the script:

Code: Select all

line 3 "put url" 
--at this point, not being connected, the script stops for an amount of seconds (in my case more then 20)
line 4 "if Json is empty" and following will run fine, adding another 10 seconds to the wait
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.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Detect internet connectivity

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

Again I am not able to replicate any delays - because the first action of the script is to determine if there is an IP address to be had.
Even if used as a blocking script, I see no delays:

Code: Select all

command putExternalIP
    local tJSON, tArray, tCount, tMaxTries = 10
    repeat 
        put URL ("https://ipv4.ipleak.net/json/") into tJSON // force ipv4 with ipleak.net
        if tJSON is not empty then
            put JSONToArray(tJSON) into tArray
            put tArray["ip"]
            exit repeat
        end if
        add 1 to tCount
        if tCount > tMaxTries then exit repeat
        wait 500 milliseconds // blocking command
        put return &  "No internet connection - attempt" && tCount && "of" && tMaxTries after msg
    end repeat
end putExternalIP
And as mentioned, you can't affect the loop by disabling wifi half way through, because the first action of the loop is to exit if there is wifi and will only continue to loop if there isn't...
So again, I'm not sure I understand your point... but as mentioned I'm still sleep deprived and maybe it's just me...

S.

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”