I’m updating some old code: to check an internet connection I used to use this snippet (posted years ago by Michael Bujardet):
Dim http As New HTTPSocket
http.yield = True
dim ih as InternetHeaders = (http.GetHeaders(“https://www.apple.com”, 1))
return (ih <> nil)
The code never fails in its response. Nevertheless I thought of replacing the deprecated HTTPSocket with URLConnection. URLConnection does not accept some of the above parameters, so I concocted the snippet below.
Now, when there is no connection, I get FALSE; yet even when I know that I do have a connection, sometimes I get False (even increasing the yeld time from 1 to 5 or more).
So I think the code actually needs improvements.
Suggestions welcome.
Var uc As New URLConnection
Var internetOk As Boolean = False
Try
Call uc.SendSync("HEAD", "https://www.apple.com", 2)
internetOk = True
Catch
End
If not internetOk Then
Try
Call uc.SendSync("HEAD", "https://www.google.com", 2)
internetOk = True
Catch
End
End
// Here you know if the internet is ok
break
Function IsInternetOK As Boolean
#Pragma BreakOnExceptions Off
Var uc As New URLConnection
Try
Call uc.SendSync("HEAD", "https://www.apple.com", 2)
Return True
Catch
End
Try
Call uc.SendSync("HEAD", "https://www.google.com", 2)
Return True
Catch
End
Return False
End Function
Thank you Rick for your better code.
Yet, starting with my connection OFF (and getting FALSE), when I set it ON (see screenshot) even waiting several seconds, I still get FALSE. Only at my second or third attempt I get TRUE.
Since the old HTTPSocket never failed, I guess it is a URLConnection problem.
BTW, I’d emphasise this happens only when I check for a connection SOON AFTER I switch my internet connection ON.
[Edited} Yet Mail or other apps get connected at once.
Perhaps it’s not a problem, but a difference, like the URLConnection needs more resources to be configured/available while the connection is being turned fully on.
If the computer is connected to the internet was discussed multiple times here on the forum. I also had problems with this. You can’t assume anything. Even worse when Little Snitch or similar are installed some connections might work and others might not.
This is my check:
if IsLittleSnitchInstalled then
Return ConnectedToInternet.LittleSnitchInstalled
Else
dim theShell as new Shell
theShell.Execute "ping -n -q -W 5 -c 1 8.8.8.8"
If theShell.ExitCode = 0 Then
Return ConnectedToInternet.IsConnected
else
Return ConnectedToInternet.notConnected
end if
end if
As far as I remember there is an Apple framework to do a proper check. This should be available in the MBS plugin.
Google. Which is why I would recommend against that method.
With modern application design you are really just supposed to try your connection and if it fails, handle that. Making preemptive connections to test has fallen out of fashion for so many reasons.
One of which (that Beatrix covers) is network filters that allow users to block individual connections based on where they go. I for one would balk at an application attempting to connect to 8.8.8.8 at launch for no reason at all - in fact I block my VPN software from doing just that.
Lots of possibilities including some specific MacOS problem. Can’t see it on a standard Windows OS with the function I provided.
I remember LOTS of discussions due to some new behavior on a MacOS version about missing few initial connections demanding retries for several seconds until that at some point the system weirdly start to become instantaneously responsive. We thought it was a new MacOS bug. Don’t know how this research ended. I do remember @Thom_McGrath running experiments.
I see the behavior / interruption with LAN connections, but it has so far not affected my asynchronous launch time DRM check-in (WAN). Trying again after the initial failure works. For me, it’s frustrating but livable.
What about trying more insistently a bit until that “MacOS warm up” ends, as:
Function IsInternetOK As Boolean
#Pragma BreakOnExceptions Off
Var uc As New URLConnection
#If DebugBuild
System.Debuglog "Contacting Google"
#EndIf
For i As Integer = 1 to 10 // find a safe lower max value if possible
Try
Call uc.SendSync("HEAD", "https://8.8.8.8", 2)
Return True
Catch
End
#If DebugBuild
System.Debuglog "retrial "+i.ToString
#EndIf
Thread.SleepCurrent(500)
Next
Return False
End Function
Now, after the warming up, it works.
But I would not make MacOS the culprit, since the problem affects only URLConnection; in fact browsers and other apps react as soon as the connection-icon (inj the menu-bar) turns ON. HTTPSocket too gets TRUE immediately.
There is also an issue that if you are behind certain gateways, they may intercept http connections and redirect them to a captive portal. So you can not be sure that an arbitrary response from a website indicates that the user is online.
You should host a script on your own website that responds with whatever query string is passed into it, randomize this in your test, and verify that the response was the same as the request.
Indeed! That is really the best approach. But in my app, for example, I have an “online/offline” indicator that needs to work without a particular website.