Summary: WinHttp.WinHttpRequest is yet another Http request class that has some features such as chunking, sadly it won't chunk asynchronously.
So someone asked a good question of SO about chunking data from a web service, the questioner complained about missing data. With the object browser it can be seen that WinHttp.WinHttpRequest supports events which can be used to trap chunks of data. It looked promising. However, after some experimentation it does not seem possible to have asynchronous chunking. One can have asynchronous request and receive the whole request or one can have a chunked synchronous request. One cannot have both chunked and asynchronous.
I give code below some that others can check my results. I tested against a Node.js slow and chunky web service from a prior blog post. In order to sink events it is necessary to use the WithEvents keyword in a class module. Here is the class module which I called WHRChunked
Option Explicit
'* Tools->References
'WinHttp Microsoft WinHTTP Services, version 5.1 C:\WINDOWS\system32\winhttpcom.dll
Private WithEvents moWHR As WinHttp.WinHttpRequest
Public msBufferedResponse As String
Public mbFinished As Boolean
Private Const mbDEFAULT_DEBUG As Boolean = True
Public mvDebug As Variant
Public Property Get bDebug() As Boolean
If IsEmpty(mvDebug) Then mvDebug = mbDEFAULT_DEBUG
bDebug = mvDebug
End Property
Public Property Let bDebug(ByVal bRHS As Boolean)
mvDebug = bRHS
End Property
Public Sub HttpGet(ByVal sURL As String, bAsync As Boolean)
On Error GoTo ErrHandler
Set moWHR = New WinHttp.WinHttpRequest
mbFinished = False
msBufferedResponse = ""
moWHR.Open Method:="GET", URL:=sURL, async:=bAsync
moWHR.send
Debug.Print "send called with bAsync=" & bAsync
SingleExit:
Exit Sub
ErrHandler:
Debug.Print "Error (" & Err.Number & ") " & Err.Description
Stop
Resume
End Sub
Private Sub moWHR_OnError(ByVal ErrorNumber As Long, ByVal ErrorDescription As String)
Debug.Print "moWHR_OnError"
End Sub
Private Sub moWHR_OnResponseDataAvailable(Data() As Byte)
Dim sThisChunk As String
sThisChunk = StrConv(Data(), vbUnicode)
Debug.Print "moWHR_OnResponseDataAvailable (" & Len(sThisChunk) & ")"
msBufferedResponse = msBufferedResponse & sThisChunk
End Sub
Private Sub moWHR_OnResponseFinished()
Debug.Print "moWHR_OnResponseFinished"
mbFinished = True
End Sub
Private Sub moWHR_OnResponseStart(ByVal Status As Long, ByVal ContentType As String)
Dim v
v = VBA.Split(moWHR.getAllResponseHeaders, vbNewLine)
Debug.Print "moWHR_OnResponseStart"
End Sub
And we need some code in a standard module to call into the class, remember this needs the web service from previous blog post.
Option Explicit
Sub Test()
Dim oWHRChunked As WHRChunked
Set oWHRChunked = New WHRChunked
oWHRChunked.HttpGet "http://localhost:34957/slowAndChunkyWebService?chunkCount=2", True
'oWHRChunked.HttpGet "http://localhost:34957/slowAndChunkyWebService?chunkCount=2", False
While oWHRChunked.mbFinished = False
DoEvents
Wend
Debug.Print oWHRChunked.msBufferedResponse
End Sub
So to experiment simply swap the above commented line for the other to see the different effects, the evidence is posted to the Immediate window using Debug.Print .
Final thoughts, I'm disappointed by this finding I hope I have it wrong. I must do a comparison table of the different features between MSXML2.XMLHTTP60, MSXML2.ServerXMLHTTP60 and WinHttpRequest.
No comments:
Post a Comment