Archived Forum PostQuestion:
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
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!
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
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
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.
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
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