vbXMLRPC.dll Getting Started
Introduction
In this example a connection is made to the (excellent) Meerkat XML-RPC Interface at the O'Reilly network. Take a look at the Meerkat specification for more info. The example was chosen to show the three different ways of compiling an XML-RPC request and how to process the response. The example set-up is detailed in a separate page (click here ...) for clarity, in this page we will assume that you have already set up the program and played around with it a little to see how it works.
A parameter-less call
Take a look at the code for the Command1_Click event. In this event we are calling Meerkat and asking it for the list of all channels. The first thing we do is set up the variables. linsRequest is an XMLRPCRequest object and is the request we are going to send to the remote server; note the use of the New keyword, we are creating the request from scratch not referencing an object so we need New. linsResponse is the XMLRPCResponse object and will hold the response from the remote server; note there is no New keyword here as we will just be using this object to hold a reference to the response returned as part of the XMLRPCRequest Submit method. linsUtility is an XMLRPCUtility object and will be used to decode some of the responses from the dll into useful strings. linsValue is an XMLRPCValue object and will be used in a For...Each loop to iterate through the contents of an XMLRPCArray; again note no New keyword. Similarly linsMember is an XMLRPCMember object and will be used in a For...Each loop to iterate through the contents of an XMLRPCStruct; again note no New keyword. llngCatId is the category ID returned by the procedure call. lstrCatTitle is the name of the category returned by the procedure call. The final line switches the mouse pointer to an hourglass, we are taking data over the internet and even on a fast line this call will take in the order of seconds.
Private Sub Command1_Click()
Dim linsRequest As New XMLRPCRequest
Dim linsResponse As XMLRPCResponse
Dim linsUtility As New XMLRPCUtility
Dim linsValue As XMLRPCValue
Dim linsMember As XMLRPCMember
Dim llngCatId As Long
Dim lstrCatTitle As String
Me.MousePointer = vbHourglass
Three lines are need to set up the connection to the remote server. The first sets the host name, note there is no http:// at the start and nothing after the .com. The second sets the host port, note this will almost always be 80, but do check the interface reference docs to check. The final line sets the host URI, note the leading "/".
linsRequest.HostName = "www.oreillynet.com"
linsRequest.HostPort = 80
linsRequest.HostURI = "/meerkat/xml-rpc/server.php"
We are passing no parameters to the remote server so all we need to set is the name of the remote method to call.
linsRequest.MethodName = "meerkat.getCategories"
With the remote server and method call set up, we use the Submit method to call the server and return an XMLRPCResponse object.
Set linsResponse = linsRequest.Submit
Now we need to validate the response. The first thing we do is check the status of the response, if it is not XMLRPC_PARAMSRETURNED then we have a problem. More sophisticated coding might be used to catch the various values that the status property can return but this is an example so let's plow on. The second thing we do is just check that we are getting one value back in the XMLRPCParams object that is the Params property and that it is an XMLRPCArray.
If linsResponse.Status <> XMLRPC_PARAMSRETURNED Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Status
ElseIf linsResponse.Params.Count <> 1 Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Params.Count & " return parameters, expecting 1"
ElseIf linsResponse.Params(1).ValueType <> XMLRPC_ARRAY Then
BugOut "Unexpected response from XML-RPC request " & linsUtility.GetXMLRPCType(linsResponse.Params(1).ValueType) & " returned, expecting an array"
End If
If we've got this far then we now need to go through the array and extract each struct. We use the For...Each code structure to achieve this. The linsResponse.Params(1).ArrayValue is the XMLRPCArray object that has come back in the response from the remote server. The XMLRPCValue object has eight methods for getting the various value types that XML-RPC supports, check the XMLRPCValue ValueType property to find out which one to call.
For Each linsValue In linsResponse.Params(1).ArrayValue
Now we are in the array we need to check first that every value is an XMLRPCStruct object.
If linsValue.ValueType <> XMLRPC_STRUCT Then
BugOut "Unexpected response from XML-RPC request " & linsUtility.GetXMLRPCType(linsResponse.Params(1).ValueType) & " returned, expecting a struct"
End If
XMLRPCStruct objects consist of XMLRPCMembers so we iterate through each member and assign it to the correct variable.
For Each linsMember In linsValue.StructValue
If linsMember.Name = "id" Then
llngCatId = linsMember.Value.IntegerValue
ElseIf linsMember.Name = "title" Then
lstrCatTitle = linsMember.Value.StringValue
End If
Next linsMember
Use standard Visual Basic code to add these to the list box.
List1.AddItem lstrCatTitle
List1.ItemData(List1.ListCount - 1) = llngCatId
Next linsValue
Don't forget to switch the mouse pointer back to its default state.
ClearCaptions
Me.MousePointer = vbDefault
End Sub
A simple parameter call
In part of the example, we are going to use a value from the list set up in the previous section as the single integer parameter to send to Meerkat to get the list of channels that are in the category. The declarations are the same as previously except that this time we have llngChanId as the channel id and lstrChanTitle as the channel name.
Private Sub List1_Click()
Dim linsRequest As New XMLRPCRequest
Dim linsResponse As XMLRPCResponse
Dim linsUtility As New XMLRPCUtility
Dim linsValue As XMLRPCValue
Dim linsMember As XMLRPCMember
Dim llngChanId As Long
Dim lstrChanTitle As String
Me.MousePointer = vbHourglass
Clear the second list otherwise we'll just keep on adding to it.
List2.Clear
linsRequest.HostName = "www.oreillynet.com"
linsRequest.HostPort = 80
linsRequest.HostURI = "/meerkat/xml-rpc/server.php"
The next difference is that we are sending a parameter to the remote server so we use the Params property to add an integer to the call. Notice the name of the method call has changed.
linsRequest.MethodName = "meerkat.getChannelsByCategory"
linsRequest.Params.AddInteger (List1.ItemData(List1.ListIndex))
The rest of the code is essentially the same, it just populates a different list box.
Set linsResponse = linsRequest.Submit
If linsResponse.Status <> XMLRPC_PARAMSRETURNED Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Status
ElseIf linsResponse.Params.Count <> 1 Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Params.Count & " return parameters, expecting 1"
ElseIf linsResponse.Params(1).ValueType <> XMLRPC_ARRAY Then
BugOut "Unexpected response from XML-RPC request " & linsUtility.GetXMLRPCType(linsResponse.Params(1).ValueType) & " returned, expecting an array"
End If
For Each linsValue In linsResponse.Params(1).ArrayValue
If linsValue.ValueType <> XMLRPC_STRUCT Then
BugOut "Unexpected response from XML-RPC request " & linsUtility.GetXMLRPCType(linsResponse.Params(1).ValueType) & " returned, expecting a struct"
End If
For Each linsMember In linsValue.StructValue
If linsMember.Name = "id" Then
llngChanId = linsMember.Value.IntegerValue
ElseIf linsMember.Name = "title" Then
lstrChanTitle = linsMember.Value.StringValue
End If
Next linsMember
List2.AddItem lstrChanTitle
List2.ItemData(List2.ListCount - 1) = llngChanId
Next linsValue
ClearCaptions
Me.MousePointer = vbDefault
End Sub
A complex parameter call
In the last part of the example, we are going to use build an XMLRPCStruct and pass this as part of the remote method call. We are going to use the channel id from the list box populated in the previous example to get the latest post in that channel. Once again, the declarations are the same as previously except that there are no non vbXMLRPC variables declared and we have an XMLRPCStruct object which will be created, populated and added to the parameters to be sent to the remote server.
Private Sub List2_Click()
Dim linsRequest As New XMLRPCRequest
Dim linsResponse As XMLRPCResponse
Dim linsUtility As New XMLRPCUtility
Dim linsStruct As New XMLRPCStruct
Dim linsValue As XMLRPCValue
Dim linsMember As XMLRPCMember
Me.MousePointer = vbHourglass
linsRequest.HostName = "www.oreillynet.com"
linsRequest.HostPort = 80
linsRequest.HostURI = "/meerkat/xml-rpc/server.php"
The next bit of code adds values to the XMLRPCStruct object. The call to the Meerkat server gets the latest post with its date and description. See the documentation at the Meerkat XML-RPC specification for the other options that can be added to the XMLRPCStruct to search and return custom information.
linsRequest.MethodName = "meerkat.getItems"
linsStruct.AddInteger "channel", (List2.ItemData(List2.ListIndex))
linsStruct.AddInteger "dates", 1
linsStruct.AddInteger "descriptions", 1
linsStruct.AddInteger "num_items", 1
linsRequest.Params.AddStruct linsStruct
Set linsResponse = linsRequest.Submit
The rest of the code rehearses aspects covered earlier.
If linsResponse.Status <> XMLRPC_PARAMSRETURNED Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Status
ElseIf linsResponse.Params.Count <> 1 Then
BugOut "Unexpected response from XML-RPC request " & linsResponse.Params.Count & " return parameters, expecting 1"
ElseIf linsResponse.Params(1).ValueType <> XMLRPC_ARRAY Then
BugOut "Unexpected response from XML-RPC request " & linsUtility.GetXMLRPCType(linsResponse.Params(1).ValueType) & " returned, expecting an array"
ElseIf linsResponse.Params(1).ArrayValue.Count < 1 Then
MsgBox "No stories to read ...", vbOKOnly + vbInformation, App.Title
Me.MousePointer = vbDefault
Exit Sub
End If
Set linsValue = linsResponse.Params(1).ArrayValue(1)
For Each linsMember In linsValue.StructValue
If linsMember.Name = "title" Then
Text1.Text = linsMember.Value.StringValue
ElseIf linsMember.Name = "link" Then
Text2.Text = linsMember.Value.StringValue
ElseIf linsMember.Name = "description" Then
Text4.Text = linsMember.Value.StringValue
ElseIf linsMember.Name = "date" Then
Text3.Text = Format(linsMember.Value.DateTimeValue, "d mmm, yyyy hh:mm:ss")
End If
Next linsMember
Me.MousePointer = vbDefault
End Sub
Oh yes ... and there is this little Sub that puts up a message box with a message and stops the program.
Private Sub BugOut(ByVal vstrError As String)
MsgBox vstrError, vbOKOnly + vbCritical, App.Title
End
End Sub
|