First off, let me say that I'm a hack of a programmer ... so my
apologies in advance if I'm not phrasing things quite right.
I'm working on an application which needs to go out to a web page,
download the content, and check a value. It needs to do this every
few minutes, so I need to put in a "timeout" control in my code so
that if the page load takes too long it will abort the transaction and
simply log an error.
However, using the MSXML2.XMLHTTP control, I just can't seem to
accurately get a "complete" state returned. I've been working with
the bAsync value on the actual GET request -- if it's set to TRUE, the
execution happens asynchronously, and I can loop out and start
checking the time. However, the ReadyState value never ever comes
back as anything other than 1 (READYSTATE_INITIALIZED). According to
the docs, I should be looking for READYSTATE_COMPLETE (value of 4) as
an indicator of a successful response.
If I set bAsync to FALSE, the code will freeze at the HTTP GET request
until it has been fulfilled. If the page is successfully returned,
READYSTATE_COMPLETE will be returned (value of 4). However, if there
is some sort of page load error, my application never recovers and
effectively dies at this point.
Any assistance is most helpful - everything I've read leads me to
believe that this should be possible. I've done it before using
InternetExplorer controls on a local machine, but this needs to be
something that a server will do - so no IE controls.
The version of my msxml3.dll file is 8.40.9419 - I'm assuming that's
the latest?
Thanks in advance!
-Douglas Toombs
-----------------BEGIN CODE BELOW (debug wscript.echo line added in do
... loop to check readystate value during execution)
Const READYSTATE_UNINITIALIZED = 0, _
READYSTATE_INITIALIZED = 1, _
READYSTATE_LOADED = 2, _
READYSTATE_INTERACTIVE = 3, _
READYSTATE_COMPLETE = 4
URL = "http://www.whatismyip.com/"
MaxLoadTime = 15
CheckPageLoadTime = 0
PageLoadStartTime = now()
Set objHTTP = CreateObject("MSXML2.XMLHTTP")
Call objHTTP.Open("GET", url, TRUE)
objHTTP.Send
Do Until objHTTP.ReadyState = READYSTATE_COMPLETE or CheckPageLoadTime
> MaxLoadTime
wscript.echo now() & " :" & objHTTP.ReadyState
PageLoadEndTime = now()
CheckPageLoadTime = DateDiff("s", PageLoadStartTime,
PageLoadEndTime)
Loop
If CheckPageLoadTime > MaxLoadTime then
wscript.echo objHTTP.ResponseText
wscript.echo "HTTP GET timed out"
else
wscript.echo objHTTP.ResponseText
wscript.echo "HTTP GET loaded in time"
end if
HTH,
Bob Barrows
--
Microsoft MVP -- ASP/ASP.NET
Please reply to the newsgroup. The email account listed in my From
header is my spam trap, so I don't check it very often. You will get a
quicker response by posting to the newsgroup.
Thanks for the prompt reply.
I checked the thread you referenced, and saw the code you'd provided.
Using the final version of the code in your message, I clipped out the
VBS portion and tried to execute it. Unfortunately, the results I'm
getting are the exact same as my original posting - readystate never
moves from 1 to 4 if i have bAsync set to TRUE.
Here's what I executed:
dim oHTTP, bRespReceived, iTimeout,body8209, t
set oHTTP = WScript.CreateObject("Microsoft.XMLHTTP")
oHTTP.onreadystatechange = GetRef("RespReceived")
oHTTP.open "GET", "http://www.whatismyip.com", True
bRespReceived = False
oHTTP.send
iTimeout = 0
t = now
Do while bRespReceived = False
iTimeout = iTimeout + 1
wscript.echo "bRespReceived = " & bRespReceived
wscript.echo "oHTTP.readystate = " & oHTTP.readystate
if datediff("s",t,now) > 5 then
body8209 = "timeout"
wscript.echo "timeout"
oHTTP.abort
on error goto 0
exit Do
end if
Loop
if oHTTP.readystate = 4 then
wscript.echo oHTTP.responsetext
end if
Sub RespReceived
if oHTTP.readystate = 4 then
bRespReceived = True
end if
end sub
And here's the output (there's several hundred loops just like this
before reaching the end, shown below):
oHTTP.readystate = 1
bRespReceived = False
oHTTP.readystate = 1
bRespReceived = False
oHTTP.readystate = 1
bRespReceived = False
oHTTP.readystate = 1
timeout
I'll try your script on another computer - not sure if I've got an
outdated XML component in my system.
-Douglas Toombs
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Are you sure you don't need more than 5 seconds to get the result back from
the remote website? It happened within the timeout period for me. Perhaps
you need to change
if datediff("s",t,now) > 5 then
to
if datediff("s",t,now) > 10 then
Bob Barrows
Doug Toombs wrote:
> Bob --
>
> Thanks for the prompt reply.
>
> I checked the thread you referenced, and saw the code you'd provided.
> Using the final version of the code in your message, I clipped out the
> VBS portion and tried to execute it. Unfortunately, the results I'm
> getting are the exact same as my original posting - readystate never
> moves from 1 to 4 if i have bAsync set to TRUE.
>
> Here's what I executed:
>
> dim oHTTP, bRespReceived, iTimeout,body8209, t
> set oHTTP = WScript.CreateObject("Microsoft.XMLHTTP")
> oHTTP.onreadystatechange = GetRef("RespReceived")
> oHTTP.open "GET", "http://www.whatismyip.com", True
> bRespReceived = False
> oHTTP.send
> iTimeout = 0
> t = now
> Do while bRespReceived = False
> iTimeout = iTimeout + 1
> wscript.echo "bRespReceived = " & bRespReceived
> wscript.echo "oHTTP.readystate = " & oHTTP.readystate
> if datediff("s",t,now) > 5 then
--
Microsoft MVP - ASP/ASP.NET
Please reply to the newsgroup. This email account is my spam trap so I
don't check it very often. If you must reply off-line, then remove the
"NO SPAM"
I tried executing the code on my home system - a brand new XP
Professional system I purchased a month ago. It has the same msxml3.dll
file version as you, plus msxml4.dll. Unfortunately, I get the same
result.... the readystate never shifts from 1 to 4 - even if I bump
the timeout to 20 which is more than enough time for the page to load.
This tels me that it's got to be something I'm missing on my system -
some component or update to XML that I haven't installed? I'm on IE
6.0.2800.1106.xpsp2.030422-1633. Any thoughts on what all I should have
installed on my system for this to work??
Baffled ....
-Doug
If you set async to false, how long does it take to get a result?
>
> This tels me that it's got to be something I'm missing on my system -
> some component or update to XML that I haven't installed? I'm on IE
> 6.0.2800.1106.xpsp2.030422-1633.
Same as mine ...
> Any thoughts on what all I should
> have installed on my system for this to work??
It should work with what you have ...
As proof, you get a result when you set async to false, correct?
>
> Baffled ....
>
> -Doug
>
Are there any firewall issues?
Bob Barrows
Correct. Setting the following line:
oHTTP.open "GET", "http://www.whatismyip.com", False
causes the program to operate properly. At least in terms of returning
a page result.
I'll try installing on a few more lab machines (Win2k, etc.) and see if
I can get any different results. But I'm absolutely stumped at this
point -- clearly, it should work but it simply refuses.
No, no firewall issues.
Thanks for your help so far!
-Douglas Toombs
Const READYSTATE_UNINITIALIZED = 0, _
READYSTATE_INITIALIZED = 1, _
READYSTATE_LOADED = 2, _
READYSTATE_INTERACTIVE = 3, _
READYSTATE_COMPLETE = 4
URL = "http://www.whatismyip.com/"
MaxLoadTime = 15
CheckPageLoadTime = 0
PageLoadStartTime = now()
Set objHTTP = CreateObject("MSXML2.XMLHTTP")
Call objHTTP.Open("GET", url, TRUE)
objHTTP.Send
Do Until objHTTP.ReadyState = READYSTATE_COMPLETE _
or CheckPageLoadTime > MaxLoadTime
wscript.sleep 10 '<<<--- Let objHTTP have some CPU time!!!
wscript.echo now() & " :" & objHTTP.ReadyState
PageLoadEndTime = now()
CheckPageLoadTime = DateDiff("s", _
PageLoadStartTime, _
PageLoadEndTime)
Loop
If CheckPageLoadTime > MaxLoadTime then
wscript.echo objHTTP.ResponseText
wscript.echo "HTTP GET timed out"
else
wscript.echo objHTTP.ResponseText
wscript.echo "HTTP GET loaded in time"
end if
--
Michael Harris
Microsoft.MVP.Scripting
Sammamish WA US
This sounds right. When I take out the echo statements in the original code,
the timeout occurs. When I put the sleep command in, the Get succeeds.
Doesn't using sleep negate the value of using an asynchronous Send? In both
cases, sync and async, you seem to need to pause your code until the data is
retrieved.
This raises the question about why similar code works in client-side code in
html pages, where sleep is not available, and nothing is done to interrupt
processing (no alert() or msgbox statements).
Not 100% sure on this, but, in one case (sync) you would possibly need to
pause the code until after the data is retrieved. In the other case (asynch)
isn't the pause simply to for the thread to yield control long enough for
other threads to get some CPU? If so, it is just an administrative thing
that perhaps should better be handled by the o/s or host, but isn't, and the
delays need not be excessive.
/Al
The OP's use of an async call is atypical for WSH hosted script. His only
purpose was apparently to implement a timeout mechanism that would
potentially be shorted than what you would get by defualt with xmlhttp.
Async calls usually involve connecting an event handler for
onreadystatechange, which the OP doesn't do in his sample code. Had he done
that, then the would have been a need for some sort of an idle loop around a
wscript.sleep ot allow events to fire and be handled.
>
> This raises the question about why similar code works in client-side
> code in html pages, where sleep is not available, and nothing is done
> to interrupt processing (no alert() or msgbox statements).
>
I would think that 'simiar ... code in html' using async calls would
invariably have event handlers in place rather than a polling loop. IE as
the host handles the message pump (WSH does it inside the sleep method) when
there aren't any event handlers running. Once the handler that *starts* the
async call completes, IE keeps the WM_blahblah messages flowing, allowing
events to fire and be handled...
Well I'll be damned ... that did the trick!
Thanks Michael!