Creating a Proxy Class Using soapsuds



Creating a Proxy Class Using soapsuds

The remoting example shown in this chapter assumed one important fact - that you were in control of both the remoting server and the client application. In the real world, this may not be (and often is not) the case. You may run into a situation where you are asked to write a client application that uses the methods hosted by a remoting server without much (if any) knowledge of how the remote class is defined. This section describes how you can build a remoting client application even if you don’t have the original remote class file used to create the client.

Viewing the Remote Class Interfaces

When the HttpChannel is used for communication with the remoting server, the remote class definition can be viewed using a normal web browser. The URI registered for the remoting server represents how the remote class is accessed via the web. To see the class interfaces, you must add the tag ?wsdl to the end of the URI:

http://192.168.1.100:9050/MyMathServer?wsdl

This URI produces the standard SOAP web page that defines the MathClass class in Listing 16.8. Each of the individual methods in the class is defined within the Web Services Definition Language (WSDL) page, along with definitions for each of the parameters and return values. Figure illustrates part of the WSDL definition.

Click To expand
Figure: The MathClass WSDL definition

Instead of manually creating the library DLL file for the remoting proxy class, you can do it with the WSDL definition and the soapsuds program.

The soapsuds Program

The .NET Framework SDK package contains the soapsuds program, which extracts class information from remote classes (you may remember this function from the wsdl program, which was discussed in the "Web Services" section in Chapter 14). The extracted information forms the DLL proxy file necessary to communicate with the remote class from a client application.

The soapsuds program offers a healthy collection of command-line options that produce many features, as described in Figure.

Figure: The soapsuds Command-Line Options

Option

Specifies

-d:domain

The domain name to use when connecting to a server

-gc

To generate C# code for the connected server

-hpn:name

An HTTP proxy server to use to connect to the server

-hpp:port

An HTTP proxy port to use to connect to the server

-ia:file

An input assembly file

-id:dir

Location of the input DLL files

-is:file

The input XML schema file

-nowp

Not to create a wrapped proxy

-oa:file

The file to save the output information

-od:dir

The directory of the output file

os:file

The file to save the XML schema information

p:password

A password to use to connect to the server

pn:namespace

The proxy namespace for the code in the generated proxy file

sdl

To generate Service Description Language (SDL) formatted files

se:url

The URL for the service endpoint to place in the output file

sn:file

The file that contains the key pair used to sign the assembly

types:info

The input type list

url:url

The URL of the service from which to retrieve the XML schema

u:username

The user name that connects to the server

wp

To create a wrapped proxy

wsdl

To generate Web Services Description Language (WSDL) formatted files

Of all these command-line options, the most common are the -url option (to specify the remote class URI), and the -oa option (to specify the DLL file to store the information.

Building the Proxy Class

The following command creates a basic DLL proxy file to replace the original remote class file:

soapsuds -url:http://192.168.1.100:9050/MyMathServer?wsdl
 -oa:MathClass.dll -nowp

The resulting MathClass.dll file then creates the client application; this is just like the original class file that was manually created (see Listing 16.8). You can also add the -gc command-line option to generate the C# code that created the DLL file (see Listing 16.13).

Listing 16.13: The soapsuds-generated MathClass.cs file
Start example
using System;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Metadata;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
[Serializable, SoapType(XmlNamespace=@"http://schemas.microsoft.com/clr/assem/_Â MathClass%2C%20Version%3D0.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3_Â Dnull", %3D0.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull")]
public class MathClass : System.MarshalByRefObject
{
  [SoapMethod(SoapAction=@"http://schemas.microsoft.com/clr/nsassem/_  Â MathClass/MathClass#Add")]
  public Int32 Add(Int32 a, Int32 b)
  {
    return((Int32) (Object) null);
  }
  [SoapMethod(SoapAction=@"http://schemas.microsoft.com/clr/nsassem/_  Â MathClass/MathClass#Subtract")]
  public Int32 Subtract(Int32 a, Int32 b)
  {
    return((Int32) (Object) null);
  }
  [SoapMethod(SoapAction=@"http://schemas.microsoft.com/clr/nsassem/_  Â MathClass/MathClass#Multiply")]
  public Int32 Multiply(Int32 a, Int32 b)
  {
    return((Int32) (Object) null);
  }
  [SoapMethod(SoapAction=@"http://schemas.microsoft.com/clr/nsassem/_  Â MathClass/MathClass#Divide")]
  public Int32 Divide(Int32 a, Int32 b)
  {
    return((Int32) (Object) null);
  }
}
End example

The proxy class file generated by soapsuds reproduces the code for the remote class, showing how each class method is defined and what parameters are within the class. After soapsuds creates the DLL file, you can write the client program, just you did when the DLL file was manually created:

csc /r:MathClass.dll MathClient.cs

The MathClient.exe file generated by this compile behaves exactly as the executable generated from the original proxy class file in Listing 16.11.

Using Wrapped Proxies

In the previous soapsuds example, which generated Listing 16.13, the -nowp option produced the generic code to access the remote class. This allows the client to access the remote class from whatever remoting server the class is hosted on. The RemotingConfiguration information is compiled into the client application to determine from where the remote class will be accessed.

Alternatively, if you do not include the -nowp option on the soapsuds command line, soapsuds creates a wrapped proxy, which handles all of the remoting communication configuration features. This includes building a constructor of the remote class, indicating how to connect to the URI specified in the soapsuds command. If you use the -gc command-line option, you can see the class constructor section:

// Constructor
  public MathClass()
  {
    base.ConfigureProxy(this.GetType(), @"http://192.168.1.100:9050/ Â
MyMathServer");
  }

When using the wrapped proxy option, the class constructor created specifies exactly where the remote class can be accessed, so no RemotingConfiguration section is needed in the client application. All the client needs to create is an instance of the remote class; the remoting system automatically knows how to access the class methods. Listing 16.14 shows the NewMathClient.cs program, which uses this technique to access the remote class.

Listing 16.14: The NewMathClient.cs program
Start example
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
public class NewMathClient
{
  public static int Main(string[] argv)
  {
   HttpChannel chan = new HttpChannel();
   ChannelServices.RegisterChannel(chan);
   MathClass obj = new MathClass();
   if (obj == null)
     System.Console.WriteLine("Could not locate server");
   else
   {
     int a = Convert.ToInt32(argv[0]);
     int b = Convert.ToInt32(argv[1]);
     int c = obj.Add(a, b);
     Console.WriteLine("a + b = {0}", c);
     c = obj.Subtract(a, b);
     Console.WriteLine("a - b = {0}", c);
     c = obj.Multiply(a, b);
     Console.WriteLine("a * b = {0}", c);
     c = obj.Divide(a, b);
     Console.WriteLine("a / b = {0}", c);
   }
   return 0;
  }
}
End example

Notice that using the wrapped proxy DLL makes the actual client code cleaner. All you need to do is create a new MathClass object using the default constructor, and the proxy wrapper does the rest. However, as discussed, the network address information of the remote class server is hard-coded into the proxy class. If the remote class server changes, the proxy class must be re-created.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows