Professional VB 2005 with .NET 3.0 (Programmer to Programmer)

An understanding of the history of the search for a decent remote method invocation (RMI) protocol is imperative to an understanding of why Web Services are so important. Each of the RMI systems created before the current Web Services model solved a particular set of problems, and you will see how current Web Services represent the next stage in the evolution of these cross-platform boundaries to solve the problems that former technologies tried to address.

The Network Angle

Throughout the history of computing, networking operations were largely handled by the operating system. UNIX, the networking host of early computing, featured a body of shell operations that provided remarkable user control over network operations. Personal computing was slower to catch up: Microsoft and Apple software didn’t inherently support networking protocols until the mid-1990s. Third-party add-ons by Novell and Banyan were available earlier, but they were only an adjunct to the operating system. The concept of the network being the computer didn’t fully infiltrate the development community until the expansion of the World Wide Web.

Application Development

Let’s break away from networking for a minute and look at how application development progressed through this time. Early time-sharing operating systems enabled several people to use the same application with its built-in data. These single-tier systems didn’t allow for growth in the system’s size, and data redundancy became the standard, with nightly batch jobs to synchronize the data becoming commonplace through the 1970s and early ’80s.

Eventually, the opportunity presented by networks became the overriding factor in systems development, and enterprise network developers began offering the loosely termed Object Request Brokers (ORBs) on their systems: Microsoft’s Transaction Server (MTS), Common Object Request Broker Architecture (CORBA), and the like. These ORBs allowed for the separation of the user interface from the business logic using tightly coupled method pooling. This three-tier architecture brings you to the present in development terms, so let’s step back and let networking catch up.

Merging the Two with the Web

The HTTP protocol was born in 1990. There had been several other information delivery protocols before, such as Gopher, but what made HTTP different were the extensibility of the related language, HTML, and the flexibility of the transport layer, TCP/IP. Suddenly, movement of many formats of data was possible in a stateless, distributed way. Software-as-a-service was born.

Over the next decade, low-level protocols supported by network systems and the Internet became a staple in applications, with SMTP and FTP providing file and information transfer among distributed servers. Remote procedure calls (RPC) took things to the next level, but they were platform specific, with UNIX implementations in CORBA and Microsoft’s Distributed COM (DCOM) leading the pack.

Enterprise development took a clue from the emerging technologies in wide area network (WAN) networking and personal computing, and development for these large-scale business systems began to mature. As usage of networks grew, developers began to solve problems of scalability, reliability, and adaptability, with the traditional flat-format programming model. Multitier development began to spread the data, processing, and user interface of applications over several machines connected by local area networks (LANs).

This made applications more scalable and reliable by accommodating growth and providing redundancy. Gradually, vendor compliance and the Java programming language provided adaptability, enabling applications to run in a variety of circumstances on a variety of platforms.

However, there was a dichotomy between the capabilities of the network and the features of the programming environment. Specifically, after the introduction of XML, there still existed no “killer app” using its power. XML is a subset of Standard Generalized Markup Language (SGML), an international standard that describes the relationship between a document’s content and its structure. It enables developers to create their own tags for hierarchical data transport in an HTML-like format. With HTTP as a transport and SOAP as a protocol, still needed was an interoperable, ubiquitous, simple, broadly supported system for the execution of business logic throughout the world of Internet application development.

The Foundations of Web Services

The hunt began with a look at the existing protocols. As had been the case for years, the Microsoft versus Sun Alliance debate was heating up among RPC programmers. CORBA versus DCOM was a source of continuing argument for developers using those platforms for distributed object development. After Sun added Remote Method Invocation to Java with Java-RMI, there were three distributed object protocols that fit none of the requirements.

Because DCOM and RMI are manufacturer-specific, it makes sense to start with those. CORBA is centrally managed by the Object Management Group, so it is a special case and should be considered separately.

RMI and DCOM provide distributed object invocation for their respective platforms - extremely important in this era of distributed networks. Both accommodate enterprisewide reuse of existing functionality, which dramatically reduces cost and time-to-market. Both provide encapsulated object methodology, preventing changes to one set of business logic from affecting another. Finally, similar to ORB-managed objects, maintenance and client weight are reduced by the simple fact that applications using distributed objects are by nature multitier.

DCOM

DCOM’s best feature is the fact that it is based on COM, surely one of the most prevalent desktop object models in use today. COM components are shielded from one another, and calls between them are so well defined by the OS-specific languages that there is practically no overhead to the methods. Each COM object is instantiated in its own space, with the necessary security and protocol providers. If an object in one process needs to call an object in another process, COM handles the exchange by intercepting the call and forwarding it through one of the network protocols.

When you use DCOM, all you are doing is making the wire a bit longer. With Windows NT4, Microsoft added the TCP/IP protocol to the COM network architecture and essentially made DCOM Internet-savvy. Aside from the setup on the client and server, the interobject calls are transparent to the client, and even to the programmer.

Any Microsoft programmer can tell you, though, that DCOM has its problems. First, there is a customer wire transport function, so most firewalls do not allow DCOM calls to get through, even though they are by nature quite benign. There is no way to query DCOM about the methods and properties available, unless you have the opportunity to get the source code or request the remote component locally. In addition, there is no standard data transfer protocol (though that is less of a problem because DCOM is mostly for Microsoft networks).

Remote Method Invocation in Java

RMI is Sun’s answer to DCOM. Java relies on a really neat, but very proprietary, protocol called Java Object Serialization, which protects objects marshaled as a stream. The client and server both need to be constructed in Java for this to work, but it further simplifies RMI because Java doesn’t care whether the serialization takes place on one machine or across a continent. Similarly to DCOM, RMI enables the object developer to define an interface for remote access to certain methods.

CORBA

CORBA uses Internet Inter-ORB Protocol to provide remote method invocation. It is remarkably similar to Java Object Serialization in this regard. Because it is only a specification, though, it is supported by a number of languages on diverse operating systems. With CORBA, the ORB does all the work, such as finding the pointer to the parent, instantiating it so that it can receive remote requests, carrying messages back and forth, and disputing arbitration and garbage collecting. The CORBA objects use specially designed sub-ORB objects called basic or portable object adapters to communicate with remote ORBs, giving developers more leeway in code reuse.

At first sight, it seems CORBA is your ace in the hole. There is only one problem - it doesn’t really work that way. CORBA suffers from the same problem Web Browsers do - poor implementations of the standards, which causes lack of interoperability between ORBs. With IE and Netscape, minor differences in the way the pages display is written off as cosmetic. When there is a problem with the CORBA standard, however, it is a real problem. Not only are looks affected, but also network interactions, as if there were 15 different implementations of HTTP.

The Problems

The principal problem of the DCOM/CORBA/RMI methods is the complexity of the implementation. The transfer protocol of each of these is based on manufacturers’ standards, generally preventing interoperability. In essence, the left hand has to know what the right hand is doing. This prevents a company using DCOM from communicating with a company using CORBA, emphasizing platform as a reason for doing business with one another.

First, there’s the problem of wire format. Each of these three methods uses an OS-specific wire format that encompasses information supplied only by the operating system in question. The problem with this is that two diverse machines cannot usually share information. The benefit is security: Because the client and server can make assumptions about the availability of functionality, data security can be managed with API calls to the operating system.

The second problem is the number of issues associated with describing the format of the protocol. Apart from the actual transport layer, there must be a schema or layout for the data that moves back and forth. Each of the three contemporary protocols makes numerous assumptions between the client and server. DCOM, for instance, provides ADO/RDS for data transport, whereas RMI has JDBC. While we can endlessly argue the benefits of one over the other, we can at least agree that they don’t play well together.

The third problem is knowing where to find broadly available services, even within your own network. We’ve all faced the problem of having to call up the COM+ MMC panel so that we could remember how to spell this component or that method. When the method is resident on a server ten buildings away and you don’t have access to the MMC console, the next step is digging through the text documentation, if there is any.

The Other Players

On a path to providing these services, we stumble across a few other technologies. While Java applets and Microsoft’s client-side ActiveX technically aren’t distributed object invocations, they do provide distributed computing and provide important lessons. Fortunately, we can describe both in the same section because they are largely the same, with different operating systems as their backbone.

Applets and client-side ActiveX are both attempts to use the HTTP protocol to send thick clients to the end user. In circumstances where a user can provide a platform previously prepared to maintain a thicker-than-HTML client base to a precompiled binary, the ActiveX and Applet protocols pass small applications to the end user, usually running a Web browser. These applications are still managed by their servers, at least loosely, and usually provide custom data transmission, utilizing the power of the client to manage the information distributed, as well as display it.

This concept was taken to the extreme with Distributed Applet-Based Massively Parallel Processing, a strategy that used the power of the Internet to complete processor-intense tasks such as 3-D rendering or massive economic models with a small application installed on the user’s computer. If you view the Internet as a massive collection of parallel processors, sitting mostly unused, you have the right idea. An example of this type of processing is provided by United Devices (www.ud.com).

In short, HTTP can provide distributed computing. The problem is that the tightly coupled connection between the client and server has to go, given the nature of today’s large enterprises. The HTTP angle did show developers that using an industry-recognized transport method solved problem number one, wire format. Using HTTP meant that regardless of the network, the object could communicate. The client still had to know a lot about the service being sent, but the network didn’t.

The goal? Distributed Object Invocation Meets the World Wide Web. The problems are wire format, protocol, and discovery. The solution is a standards-based, loosely coupled method invocation protocol with a huge catalog. Microsoft, IBM, and Ariba set out in 1999 to create just that, and generated the RFC for Web Services.

What All the Foundations Missed

You may notice that in reviewing the majority of the earlier services there has been little mention of language. This is because it was a problem overlooked by the foundations. Even RMI didn’t recognize the reality that you can’t make everyone use the same language, even a great language.

HTTP - A Language-Independent Protocol

What we need is a language-independent protocol that accommodates a standard wire transfer, protocol language, and catalog service. Java with Remote Scripting and ActiveX taught us that HTTP is the wire transfer of choice. Why? What does HTTP do that is so great? First, it is simple. The header added to a communication by HTTP is straightforward enough that power users can type it at a command prompt if they have to. Second, it doesn’t require a special data protocol; it just uses ASCII text. Another reason is that HTTP traffic can easily get through firewalls (port 80 is usually open). Finally, it is extensible. Additional headers can be added to the HTTP header for application-specific needs, and any intermediary software can just ignore it.

XML - Cross-Language Data Markup

Now that we have a standard wire transfer protocol that we know works, we need a language and a transport mechanism. Existing languages don’t really have data description functions, aside from the data management object models such as ADO. XML fits the bill because it is self-describing. There’s no need for the left hand to know what the right hand is doing. An XML file transported over HTTP doesn’t need to know the answering system’s network protocol or its data description language. The concepts behind XML are so light and open that everyone can agree to support them. In fact, almost everyone has. XML has become the ASCII of the Web.

XML is important to Web Services because it provides a universal format for information to be passed from system to system. We knew that, but Web Services actually uses XML as the object invocation layer, changing the input and output to tightly formatted XML, making it platform and language independent.

SOAP - The Transfer You Need

Enter Simple Object Access Protocol (SOAP), which uses HTTP to package essentially one-way messages from service to service in such a way that business logic can interpolate a request/response pair. In order for your Web page to get an example, a SOAP request would look something like this:

POST /Directory HTTP/1.1 Host: Ldap.companyname.com Content-Type: text/xml; charset="utf-8" Content-Length: 33 SOAPAction: "Some-URI"\vs <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encoding> <SOAP-ENV:Body> <m:FindPerson xmlns:m="Some-URI"> <NAME>Gates</NAME> </m: FindPerson> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

This is an HTTP page request, just like one you’d see for an HTML page except that the Content-Type specifies XML, and there is the addition of the SOAPAction header. SOAP has made use of the two most powerful parts of HTTP: content neutrality and extensibility. Here is the response statement from the server:

HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" Content-Length: 66 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encoding/> <SOAP-ENV:Body> <m:FindPersonResponse xmlns:m="Some-URI"> <DIRECTORY>Employees <PERSON> <NAME>Bill Gates</NAME> <FUNCTION>Architect <TYPE>Web Services</TYPE> </FUNCTION> <CONTACT> <PHONE TYPE=CELL>123-456-7890</PHONE> <PHONE TYPE=HOME>555-111-2222</PHONE> </CONTACT> </PERSON> </DIRECTORY> </m: FindPersonResponse > </SOAP-ENV:Body> </SOAP-ENV:Envelope>

SOAP enables you to send the XML files back and forth among remote methods. It is similar to XML-RPC, a protocol developed by Dave Winer in parallel with the SOAP protocol. Both protocols provide similar structures, but it is the official SOAP protocol that is used by Visual Basic and the entire .NET platform.

SOAP isn’t specific to .NET, either. The SOAP Toolkit is another set of tools that Microsoft’s Web Services Team provides free of charge. It contains a wonderful WSDL editor, retrofit objects for Windows 2000 and Windows NT4 servers, and more. You can find it at http://msdn.microsoft.com/webservices.

Web Services Description Language

A Web Services Description Language (WSDL) document is a set of definitions that is utilized to describe the interface of any of your Web Services. Six elements are defined and used by the SOAP protocol: types, message, portType, binding, port, and service. Essentially adding another layer of abstraction, the purpose of WSDL is to isolate remote method invocations from their wire transport and data definition language. Once again, it is a specification, not a language, so it is much easier to get companies to agree to its use.

Because WSDL is just a set of descriptions in XML, it is not so much a protocol as a grammar. Following is the sample service contract for the HelloWorld Web Service you’ll be building shortly. You can see this file by visiting http://localhost/HelloWorldExample/Service.asmx?WSDL using your Web browser after you create the examples:

<?xml version="1.0" encoding="utf-8" ?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://localhost/webservice" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://localhost/webservice" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"> <wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://localhost/webservice"> <s:element name="HelloWorld"> <s:complexType /> </s:element> <s:element name="HelloWorldResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" /> </s:sequence> </s:complexType> </s:element> </s:schema> </wsdl:types> <wsdl:message name="HelloWorldSoapIn"> <wsdl:part name="parameters" element="tns:HelloWorld" /> </wsdl:message> <wsdl:message name="HelloWorldSoapOut"> <wsdl:part name="parameters" element="tns:HelloWorldResponse" /> </wsdl:message> <wsdl:portType name="WebServiceSoap"> <wsdl:operation name="HelloWorld"> <wsdl:input message="tns:HelloWorldSoapIn" /> <wsdl:output message="tns:HelloWorldSoapOut" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="WebServiceSoap" type="tns:WebServiceSoap"> <wsdl:documentation> <wsi:Claim conformsTo="http://ws-i.org/profiles/basic/1.0" xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" /> </wsdl:documentation> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="HelloWorld"> <soap:operation soapAction="http://localhost/webservice/HelloWorld" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name="WebServiceSoap12" type="tns:WebServiceSoap"> <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="HelloWorld"> <soap12:operation soapAction="http://localhost/webservice/HelloWorld" /> <wsdl:input> <soap12:body use="literal" /> </wsdl:input> <wsdl:output> <soap12:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="WebService"> <wsdl:port name="WebServiceSoap" binding="tns:WebServiceSoap"> <soap:address location="http://localhost:40718/Reuters/WebService.asmx" /> </wsdl:port> <wsdl:port name="WebServiceSoap12" binding="tns:WebServiceSoap12"> <soap12:address location="http://localhost:40718/Reuters/WebService.asmx" /> </wsdl:port> </wsdl:service> </wsdl:definitions>

This is what makes it all work. Notice that each of the inputs and outputs of the HelloWorldResponse function is defined as an element in the schema. The .NET Framework uses this to build library files that understand how best to format the outgoing requests, so no matter what operating system develops the WSDL, as long as it is well formed according to the WSDL specification, any type of application (it doesn’t necessarily need to be a .NET application) can consume it with a simple SOAP request.

In fact, IIS with the .NET Framework is set up to use the WSDL document in order to provide a great auto-generated user interface for developers and consumers to check out and test Web Services. After removing the ?wsdl from the preceding URL, you’ll see a very nicely formatted documentation screen for the service. Click the function name and you’ll get the screen shown in Figure 26-2. This is all dynamically generated based upon the contents of the WSDL document, which is itself dynamically generated by .NET.

Figure 26-2

The WSDL document can also be expanded in order to define your own descriptions. You can use the Description property of both the WebService() and WebMethod() attributes to provide more details for this .NET-generated test page for your XML Web Services.

Категории