Question:
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