Archived Forum Post

Index of archived forum posts

Question:

How to check if internet is availabe

Jul 19 '14 at 13:28

I'm using VFP 9 to develop business software.

I use Chilkat.Http to access some services in the web.

Some of my clients sometimes, temporarily, may not have internet access and because of it their computer hangs.

How can I check if internet access is available before using Chilkat.Http.

Best regards, Americo


Answer

It's true that my value for ConnectTimeout was a bit high; I only check that once when the application loads, and I want to give it a fighting chance with all the network traffic on the client's machine... If I were to check the connection from time to time and didn't want to hurt my performance I would probably use 200-500. I would think, and this is just a guess, that 2 might be a little low.

I tried your example, and it failed on line 5, undefined variable. If that is the exact code you used, and your language is case sensitive, that might be part of the cause of your failure. After a quick fix it worked just fine (running windows 7).

As for the question of hanging- your on the right track. There is a setting missing, I forgot the heartbeat property! Thanks for helping me to catch that. I have modified my code as follows

var http = new ActiveXObject('Chilkat.Http');    
var success = http.UnlockComponent('****');
var html = '';

if (success) {
    http.ConnectTimeout = 200;
    http.HeartbeatMs = 200;

    html = http.QuickGetStr('http://www.mysite.com/connected.txt');

    if (html=='true') {                         // internet connectivity found
        RC.ID('ChooseEmail')['canEmail'] = true;
    }    
    else {
        RC.ID('ChooseEmail')['canEmail'] = false;
    }        
}

And tested it with and without internet connectivity. The results are without hanging, and return the expected results :)

Without setting the HearbeatMs property I don't think it can even check the ConnectTimeout for a while... so...

Thank you for finding this critical flaw in my implimentation, I'll be sending out this fix with my next updates!


Answer

Another option is to use a the background threading feature of the ChilkatHTTP object to prevent your UI thread from hanging.

This example (in VB6, but should be easy enough to port to your language) demonstrates uses a Timer and the ChilkatHTTP object with the UseBgThread property set to 1 to continually check the Internet connection by attempting to get data from servers with known high availability (google.com, microsoft.com, etc...). It also tries to minimize the amount of time it hits those servers so that we aren't hammering them, but if you have your own domains you can use those (I recommend at least 2 different domains on different servers to know that it's not just your server that is down).

Option Explicit

Private WithEvents mo_Http As CHILKATHTTPLib.ChilkatHttp

Private m_ConnectedToInternet As Boolean
Private m_TestErrorCount As Long
Private m_MyServerUrl As String  ' URL to your own server for the bulk of testing

Private mo_TestUrls As Collection   ' Collection of known high-availability server list for secondary testing

Private Sub Form_Load()
   ' Set up your own server URL for the bulk of testing to avoid unnecessarily hitting other company's servers
   ' If the call to our server fails, only then will we try known high-availability servers (below)
   m_MyServerUrl = "http://www.MY_OWN_URL.com"

' Create a collection of URLs that are almost guaranteed to be available
   ' if the user's Internet connection is working
   Set mo_TestUrls = New Collection
   With mo_TestUrls
      .Add "http://www.google.com"
      .Add "http://www.microsoft.com"
      .Add "http://www.yahoo.com"
      .Add "http://www.apple.com"
   End With

' Create ChilkatHTTP object and set it up for background processing
   Set mo_Http = New CHILKATHTTPLib.ChilkatHttp
   With mo_Http
      .UnlockComponent "STATSLHttp_fCyJTNvsYE8t"
      .UseBgThread = 1  ' This will prevent UI thread from hanging by running test in a background thread
      .ConnectTimeout = 3
      .ReadTimeout = 3
   End With

' Create a timer object to continually test for Internet connectivity
   With Me.Timer1
      .Interval = 250   ' Short interval in MS
      .Enabled = True
   End With
End Sub

Private Sub Form_Unload(Cancel As Integer)
   ' Cleanup
   Me.Timer1.Enabled = False

' Make sure HTTP background thread cleans up before we leave the program to prevent crash
   If mo_Http.BgTaskRunning Then
      mo_Http.BgTaskAbort
      Do While mo_Http.BgTaskRunning
         Sleep 100
      Loop
   End If
   Set mo_Http = Nothing
End Sub

Private Sub Timer1_Timer()
   Static s_LastChecked As Date  ' The last time a test was run
   Static s_CheckSeconds As Long ' The number of seconds to wait between tests
   Static s_TestStarted As Boolean   ' A test has been started

Dim l_TestUrl As String ' The URL we will be testing on this pass

Me.Timer1.Enabled = False

If (mo_Http.BgTaskRunning = 0) And Not s_TestStarted Then
      ' There is no test running
      If DateDiff("s", s_LastChecked, Now) > s_CheckSeconds Then
         ' Enough time has passed to warrant a new test

s_LastChecked = Now  ' Mark the test start time so the next test will be appropriately delayed
                              ' This prevents server hammering

If m_TestErrorCount = 0 Then
            ' No errors yet, so test our own server so we aren't abusing other's resources
            l_TestUrl = m_MyServerUrl
         Else
            ' Our server test failed! Check a known high-availability server to see if it fails too

' Get the next queued test URL
            l_TestUrl = mo_TestUrls.Item(1)
            ' Move the next queued test URL to the end of the queue
            mo_TestUrls.Remove 1
            mo_TestUrls.Add l_TestUrl
         End If

Debug.Print "Checking URL: " & l_TestUrl

s_TestStarted = True ' Mark the start of the test
         mo_Http.GetHead l_TestUrl     ' Get the URL in th background
      End If
   End If

If (mo_Http.BgTaskRunning = 0) And s_TestStarted Then
      ' The last test has finished processing
      s_TestStarted = False   ' Mark the test complete

If mo_Http.BgTaskSuccess = 1 Then
         ' Test succeeded, connected to Internet!

If Not m_ConnectedToInternet Then
            ' Internet is back up!
            ' You could raise an event here if you are using this code in a class
            ' e.g. RaiseEvent InternetUp()

Debug.Print "Internet UP!"
         End If

m_TestErrorCount = 0
         m_ConnectedToInternet = True
         s_CheckSeconds = 10  ' Leave lots of time between tests under the assumption that we will be connected for a while
                              ' and to avoid hammering test servers

Else
         ' Test failed! We might not be connected to the Internet (or the site may just be down)
         ' We will need 2 failures from 2 different URLs to confirm that the Internet is down
         m_TestErrorCount = m_TestErrorCount + 1

If m_ConnectedToInternet Then
            s_CheckSeconds = 0   ' Test more often since we are disconnected and we want to know when the Internet is back ASAP
                                 ' This won't hammer the servers since we aren't connected to the Internet

If m_TestErrorCount > 1 Then
               ' More than 1 test failed! Assume we are disconnected from Internet.

' You could raise an event here if you are using this code in a class
               ' e.g. RaiseEvent InternetDown()

Debug.Print "Internet DOWN!"
            End If
         End If

If m_TestErrorCount > 1 Then
            ' Reset the error counter to test our own company server first again
            m_TestErrorCount = 0
            m_ConnectedToInternet = False
         End If
      End If

mo_Http.CloseAllConnections   ' Release "keep-alive" servers to prevent subsequent call failure
   End If

Me.Timer1.Enabled = True
End Sub

Answer

This doesn't answer your questions "strictly" as it was posed... so it might not be the solution that your looking for; but I actually had the exact same issue recently, and the following is a snippet that shows how I was able to determine whether internet connectivity is currently present to allow the emailing of certain resources.

I decided to use a known resource to show connectivity, but I used the HTTP object to do so. If it can read the file then we are connected... the remote file contained only one word: "true" (unquoted)

var http = new ActiveXObject('Chilkat.Http');    
var success = http.UnlockComponent('****');
var html = '';

if (success) {
    http.ConnectTimeout = 2000;

    html = http.QuickGetStr('http://www.mysite.com/connected.txt');

    if (html=='true') {                         // internet connectivity found
        RC.ID('ChooseEmail')['canEmail'] = true;
    }    
    else {
        RC.ID('ChooseEmail')['canEmail'] = false;
    }        
}

And technically, if chilkat can't download a 4 byte file- then it's not going to satisfy any of my other HTTP needs


Answer

Thanks for the answer.

The code I use in the beginning of that program is:

loxml = CreateObject('Chilkat.Xml')
loHttp = CreateObject('Chilkat.Http')
lnSuccess = loHttp.UnlockComponent("**********")
IF (lnSuccess = 1) THEN
    lohttp.ConnectTimeout = 2
    lnSuccess = loHttp.Download("http://www.elabora.pt/versoes.xml",SYS(2003)+"\versoes.xml")
    IF (lnSuccess = 1) THEN
        loxml.LoadXmlFile(SYS(2003)+"\versoes.xml")

The file "versoes.xml" is only 149 bytes long.

The strange thing is that only some computers, mainly using Windows XP, hangs when they don't have internet connection, yet most of the machines don't hang.

Could it be the ConnectTimeout too low?

I putted it low because when there was no internet connection it toke too long to advance to the next step.


Answer

Just my 2cents - 7-19-14 If a windows computer is being used to check for internet connection, Internet Explorer is installed as part of windows....so I use the Internet Explorer Wininet.DLL

DEFINE FLAG_ICC_FORCE_CONNECTION 1

DECLARE LONG InternetCheckConnection IN Wininet.DLL STRING Url, LONG dwFlags, LONG RESERVED lcUrl = "http://www.google.com" IF InternetCheckConnection(lcUrl, FLAG_ICC_FORCE_CONNECTION, 0) <> 0 RETURN .T. ENDIF CLEAR DLLS InternetCheckConnection RETURN .F. ENDFUNC

Hope this helps