Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Web Development

Simplifying Web Service Integration


Neal is owner of NC Software and can be contacted at [email protected].


Developers these days are overloaded with ideas, but have limited time to implement them. Consequently, we've become increasingly reliant on third-party tools to encapsulate development work that can be easily utilized in COM-compliant applications such as with Visual Basic 6.

As owner of NC Software (www.nc-software.com) and developer of Logbook Pro pilot logbook and AVCataloger media cataloging software, I've found that third-party tools save development time and provide expertise that would have taken us years to acquire.

For instance, as Logbook Pro matured, we wanted to bring in a service-oriented architecture (SOA), but were challenged with legacy VB6 code paired against modern programming practices (aka .NET). We are web-service fanatics and take advantage of the SOA theme anywhere possible. However, our first challenge was to lose the integrated Update Service that we subscribed to from Macrovision. Although a great service, it was too expensive for our use. Moreover, we knew its functionality was something we could do ourselves via web services. With this in mind, we built a SQL Server database with a web-service middle tier, allowing our own update service to drive any application from our web applications, VB6 applications, and new editions of our software being developed in Visual Studio 2005.

Building the update system resulted in a huge cost savings because we were able to shed the Macrovision Update Service. The challenge we then faced was integrating not only web services into our VB6 applications, but also a download mechanism and XML parser with minimal effort. Because Logbook Pro has been in existence for nine years and all of our current development efforts are in .NET, we didn't want to expend too much effort. This is where the IP*Works! Internet Toolkit from /n Software (www.nsoftware.com/ipworks) came into the picture.

The software update system first involved making a web service call. Using the IP*Works! system was easy to integrate with only one item of interest—the requirement to add the SoapRpcMethod() attribute to the web methods; see Listing One.

<WebMethod(), SoapRpcMethod()> _
Public Function HelloWorld(ByVal p As String) As String
    If p.ToLower = "test" Then
        Return "Hello World"
    Else
        Return "Invalid Parameter"
    End If
End Function
Listing One

You can then use the Software Web Service Proxy Generator in the Helper Applications section (www.nsoftware.com/kb/default.aspx) in the knowledgebase, which opens the page at www.nsoftware.com/kb/apps/wspg. Enter the address to your web service and generates the code to make the web service call from your VB6 application. Listing Two makes our web service call using the IP*Works! SOAP component.

Public Function HasUpdates() As Boolean
    On Error GoTo Err_Updates
    Screen.MousePointer = 11
    SOAP1.reset
    SOAP1.ValueFormat = vfText
    SOAP1.MethodURI = "http://
       webservices.nc-software.com/UpdateService"
    SOAP1.ActionURI = 
       "http://webservices.nc-software.com/
          UpdateService/GetUpdateByMajMinRev"
    SOAP1.URL = 
       "http://webservices.nc-software.com/20/ 
          UpdateService/UpdateService.asmx"
    SOAP1.method = "GetUpdateByMajMinRev"
    SOAP1.AddParam "XMLProductCode", XMLProductCode
    SOAP1.AddParam "iMajor", APP.Major
    SOAP1.AddParam "iMinor", APP.Minor
    SOAP1.AddParam "iRevision", APP.Revision
    SOAP1.AddParam "p", "mypassword"
    SOAP1.SendRequest
    
    Dim strReturn As String
    strReturn = SOAP1.returnValue

    If Trim$(strReturn) = "" Then
        HasUpdates = False
        Screen.MousePointer = vbDefault
        Exit Function
    End If
    
    If InStr(strReturn, "|") > 0 Then
        HasUpdates = True
        Dim arr As Variant
        arr = Split(strReturn, "|")
        With ncUpdateInfo
            .UpdateTitle = arr(0)
            .BriefDescription = arr(1)
            .DetailedDescription = arr(2)
            .DownloadURL = arr(3)
            .InfoURL = arr(4)
            .DownloadSize = arr(5)
            .IsCritical = CBool(arr(6))
        End With
    Else
        HasUpdates = False
    End If
        Screen.MousePointer = vbDefault
Exit Function

Err_Updates:
    HasUpdates = False
    Screen.MousePointer = vbDefault
End Function
Listing Two

As you can see, the SOAP component (one of more than 40 included in IP*Works!) makes web-service integration straightforward in any ActiveX-compliant application.

Once we could identify when an update was available, we needed an easy method to download the update file and show progress, which can be a challenge even in .NET. The HTTP control in the IP*Works! suite performs downloads, and the /n sample code shows how to display download progress, making it easy to wire up a progress bar to provide feedback to the end-user during download. Listing Three is the code for the update dialog and downloading of the available updates.

Private Sub DoDownload()
    On Error GoTo Err_Download
    Screen.MousePointer = 11

    If Dir(updateFile) <> "" Then
        FileSystem.Kill updateFile
    End If
    
    With HTTP1
        .LocalFile = updateFile

        .Get ncUpdateInfo.DownloadURL
    End With
    Exit Sub

Err_Download:
    Screen.MousePointer = vbDefault
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, _
                             UnloadMode As Integer)
    HTTP1.Interrupt
End Sub

Private Sub HTTP1_Disconnected(StatusCode As Integer, _
                               Description As String)
    If StatusCode <> 0 Then
        If Dir(updateFile) <> "" Then
            FileSystem.Kill updateFile
        End If
    End If
    EnableButtons
End Sub

Private Sub HTTP1_EndTransfer(Direction As Integer)
    Me.cmd(1).Caption = "&Update Now"
    Me.cmd(2).Caption = "&Close"
    Me.cmd(1).ToolTipText = 
                  "Click to begin the update and 
                   close Logbook Pro"
    Me.progBar.Visible = False
    Screen.MousePointer = vbDefault
    EnableButtons
End Sub

Private Sub HTTP1_Error(ErrorCode As Integer, _
                        Description As String)
    If Dir(updateFile) <> "" Then
        FileSystem.Kill updateFile
    End If
    EnableButtons
End Sub

Private Sub HTTP1_Header(Field As String, _
                         Value As String)
    On Error Resume Next
    If UCase(Field) = "CONTENT-LENGTH" Then
        lngFileSize = CLng(Value)
    End If
End Sub

Private Sub HTTP1_StartTransfer(Direction As Integer)
    DisableButtons
    Me.progBar.Visible = True
    Me.progBar.FloodPercent = 0
End Sub

Private Sub HTTP1_Transfer(Direction As Integer, _
                         BytesTransferred As Long, _
                           Text As String)
    Me.progBar.FloodPercent =
         (BytesTransferred / lngFileSize) * 100
End Sub
Listing Three

Internet integration was also straightforward with IP*Works!, and as Logbook Pro continued to grow, we added support for both Palm OS and Pocket PC applications. We recently rewrote our Logbook Pro Pocket PC Companion using the .NET Compact Framework in Visual Studio 2005 and wanted to use a persisted DataSet for our data store on the device. We then wanted to be able to read this data on the PC after transferring the saved DataSet using RAPI and ActiveSync. The DataSet is a great storage means for making XML data persistent and readable, and in the small data requirement of the Logbook Pro Pocket PC Companion, this was ideal. However, this left us a challenge on the PC side of Logbook Pro—having to easily consume the XML-generated data using the DataSet.WriteXML method, parse it, and get it into the Microsoft Access back-end that Logbook Pro uses on the PC side. Of course, we could have used various XML options (xpath and the like). However, we have to assume our users don't have MSXML on their computers and we didn't want to bloat our installer any further. We're already pushing a 15-MB download and we truly wanted to keep this small, so the logical choice was to use the XMLp (XML Parser), which is part of the IP*Works! collection. Again, Software saved time by making the task of reading XML in VB6 simple; see Listing Four, which consumes the XML from our Pocket PC Companion product.

With XMLp1
        .Input strXML
        .XPath = "/dsLogbook"
        Dim I As Integer
        Dim j As Integer

        For I = 1 To .XChildren
            .XPath = "/dsLogbook/[" & I & "]"
            Select Case .XElement
                Case "PDACertificates"
                    Set rst = 
                       mydb.OpenRecordset(
                          "PDACertificates", dbOpenDynaset)
                    rst.AddNew
                    rst.Fields("CertificateID").Value = .Attr("CertificateID")
                    rst.Fields("Grade").Value = .Attr("Grade")
                    rst.Fields("Number").Value = .Attr("Number")
                    rst.Fields("DateIssue").Value = GetPPCDate(.Attr("DateIssue"))
                    rst.Fields("Remarks").Value = .Attr("Remarks")
                    rst.Update
                    rst.Close
                    Set rst = Nothing
               End Select
        Next
    End With
Listing Four

Conclusion

Taking advantage of third-party components such as IP*Works! can be a great time saver. And because I assume that the developers who created these components are smarter than me, I rest assured that I made the right choice in using available third-party technologies. DDJ


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.