Compare .NET Remoting to Web Services
Compare .NET remoting to ASP.NET Web services to determine which solution is right for your application.
by Randy Holloway

Web Services in the Enterprise 2002

Technology Toolbox: C#, ASP.NET, XML

The .NET Framework offers two mechanisms to support distributed application development and integration: .NET remoting and ASP.NET Web services. Both these techniques support developing distributed applications and application integration, but you need to consider how they differ before choosing one implementation over the other. I'll sort these differences out by comparing and contrasting .NET remoting and ASP.NET Web services, reviewing samples for each type of implementation and reviewing issues related to deploying these applications.

Remoting is .NET's answer to DCOM; it allows your programs and software components to interact across application domains, processes, and machine boundaries. This enables your applications to leverage remote resources in a networked environment. Remoting with .NET can take advantage of different transport mechanisms, including native support for a binary TCP-based protocol and a Simple Object Access Protocol (SOAP)/HTTP-based protocol. This flexibility makes .NET remoting an ideal choice for certain types of application integration.

You can use ASP.NET Web services to leverage SOAP-based messaging in your applications. ASP.NET Web services abstract all the plumbing from you, enabling you to write code, expose your methods as WebMethods, and deploy the code for consumption by remote clients. In addition, you can reference Web services easily from your .NET client applications.

Remoting involves using object references to facilitate communication between client applications and server objects. The .NET Framework's remoting infrastructure enables you to access remote objects while abstracting the details of the remoting internals, such as protocols for communication and activation. A client can invoke a method on a remote object by using a proxy object. This initiates the remoting infrastructure to route that call to the server process, invoke the server object's method, then initiate the return value to the client proxy. Unlike Web services, .NET remoting is designed to work within the .NET Framework, primarily with other .NET applications. The remoting services aren't designed to support interoperability with other platforms, which is different from the standards-based approach used for developing Web services.

Get Started With Remoting
Get started with .NET remoting by reviewing the RemoteResource class (see Listing 1). First, create a method that implements some simple data access code. Build a SqlConnection object with a connection established to the Northwind database. Then create an instance of a DataSet object, populate it with the query results produced by the SqlDataAdapter, and return the DataSet value. The RemoteResource object inherits from the base class MarshalByRefObject. Objects that don't inherit from MarshalByRefObject marshal by value, meaning that you pass a copy of the object across application domain boundaries. In this case, the client application simply maintains a reference to the server object through its proxy, and the client resolves all calls to the server object within that context.

Once you develop the server object, you need to deploy this object to make it accessible by remote clients. One way to deploy .NET remoting components is through Internet Information Server (IIS). This enables the object to communicate bidirectionally through the HTTP transport channel using a SOAP formatter or a binary formatter. IIS supports both formatter mechanisms and responds based on the client's formatter selection. To install the component, you need to create a virtual directory in IIS, configure the directory to support anonymous authentication, and create a subdirectory named bin under that directory. Then copy the assembly containing the remoting server class into the bin directory, and create a web.config file in the virtual directory containing this XML data:

<configuration>
   <system.runtime.remoting>
      <application>
         <service>
            <wellknown 
               mode="Singleton" 
                  type="NRServer.
                  RemoteResource, 
                  NRServer"
                  objectUri=
                  "RemoteResource.
                  soap" />
         </service>
      </application>
   </system.runtime.remoting>
</configuration>

This configuration file contains information defining the remoting server's type, mode, assembly, and objectUri. The type attribute reflects the remoting server's type and its assembly name. You use the mode attribute to define this server-activated object's activation type. The remoting server creates a server-activated object, such as the one in this example, when the client invokes the first method through its proxy. This is similar to Web services' stateless nature. Server-activated objects can be of a Singleton or SingleCall type. For Singleton objects, only one instance is activated to service client requests. For SingleCall objects, the remoting system creates a new instance for each client method invoked. The objectUri attribute's value RemoteResource.soap ensures that the remoting request is routed to the correct endpoint. The remoting server is complete once you've completed these steps. When exposing a remoting server on a public network, give careful consideration to the requirements for securing that resource. The configuration described here is only suitable for managed network environments or for applications where securing access to the remoting server isn't important.

Now that you've established the remoting server, you need to develop a client application to access the remote resource. Ensure that your client application can access the server object's type information. You can distribute the server object's assembly to the client, but this can be unsuitable in some instances where you don't want the client application to have direct access to the type's implementation. An example of such a case could be to preserve intellectual property rights. With access to the assembly, the file could be subject to disassembly and review without your permission.

Build a Solitary Client
For this sample client application, you'll build a "solitary client" using the Soapsuds.exe tool. A solitary client is an application that maps to a static remoting server, because the proxy class generated by Soapsuds.exe is compiled into your client, leaving you unable to change it. Use these command-line arguments to generate the proxy class for the NRServer assembly:

Soapsuds.exe -ia:NRServer -nowp -gc

This enables you to generate a proxy class that contains the type information in XML form for the remoting server. You can then compile this proxy class with the client application.

This technique works only for remoting through the HTTP transport channel. To access the remote server object, the client application must contain a reference the proxy class generated through Soapsuds. The client application must also invoke RemotingConfiguration.Configure() from the System.Runtime.Remoting namespace. This configuration function takes the client application configuration file as an argument, and performs the remoting configuration required for the client to access the remoting server. The client's configuration file should include this XML data (see Listing 2).

Similar to the server's configuration file, this file references the type and assembly used for the client proxy and also specifies the URL used by the code to access the remote server resource. This URL should correspond to the virtual directory containing the server's assembly, and it should contain the objectUri as specified by the server. The client configuration also contains a channels element, enabling you to specify the transport channel and formatter to use. In this case, you're using the HTTP channel with the binary formatter.

Once you set up the client application for its remoting configuration and it has a reference to the proxy class generated by Soapsuds, the remaining code to access the remote server object is minimal:

DataSet dsRemote = new DataSet();
RemoteResource myRR = new 
   RemoteResource();
dsRemote = myRR.GetData();

This code creates an instance of the DataSet object and the proxy class for RemoteResource. You then call the RemoteResource class's GetData() method, which initiates communication with the server object to invoke the GetData method, and returns the DataSet object containing the data as queried by the server.

You can also accomplish the application integration task in the previous .NET remoting example with ASP.NET Web services. Web services using SOAP and HTTP essentially provide another form of remote method invocation, although they're different architecturally from .NET remoting. One key difference is that the code and configuration required to develop and deploy Web services is simpler. You need to create an ASP.NET Web service project to create a Web service that's comparable to your remoting server. Within that project, you then create a WebMethod named GetData that's identical to Listing 1's example. The Web service application is deployed automatically to an IIS server and works by default on many machines, but you do need to consider the specific security requirements for applications that are exposed to public networks or that contain sensitive data, such as the .NET remoting server.

Add a Web Reference
The client implementation for the Web service is a simple process with the .NET Framework. The client application needs a Web reference, which enables the client to access the Web Services Description Language (WSDL) required to implement the Web service. You can add a reference to the Web service in your client application by following the Add Web Reference menu available through the Solution Explorer in VS.NET, and providing the URL for the service. Once the reference is available, the code to access the service is straightforward. For this example, the code to invoke the Web service's GetData method looks like this:

DataSet dsRemote = new DataSet();
   localhost.Service1 wsRR = new 
   localhost.Service1();
   dsRemote = wsRR.GetData();

Like the remoting code shown previously, the object reference used to call the Web service acts as a proxy component and facilitates communication between the client and the server through SOAP and HTTP. The Web service's transport mechanism is the same as the remoting example shown, and the examples make it clear that the Web services code is much easier to implement—it's less code.

You might wonder why you'd want to select .NET remoting over Web services. There are several possible answers to this question, and one of the key answers is application performance. Next, you'll review of the performance of your respective remoting applications.

To demonstrate one of the key differences between .NET remoting server objects and ASP.NET Web services, take a look at both solutions' performance using the server application examples discussed previously. Implement these tests by creating a client application using a Windows Forms project named NRWSClient. Implement this client application by building a form containing two button controls, a textbox for a loop counter input, and four labels.

For one of the buttons, use the Click event's event procedure to implement the test code for the .NET remoting implementation. For the other, implement the Web services test code (see Listing 3 for the event procedure to trigger to test the Web service). In this code, you create a timer mechanism to capture the start time, the end time, and the total time span for executing the Web services code. Then, you output those results to the form (see Figure 1). Note that the timer captures the start time immediately prior to initiating the for loop where you call the WebMethod, and the timer captures the end time immediately following this loop's exit.

Figure 1. Compare Solution Performance

The client implementation for the .NET remoting server object has two key differences from the Web services implementation. First, the remoting services require you to specify the client application's configuration values in the NRWSClient.exe.config file. You pass this filename as an argument to the RemotingConfiguration.Configure method, invoked in the application's Form_Load event procedure. Second, you invoke the Remoting object by using the object's proxy class—in this case, named RemoteResource. The test code is identical in all other respects.

Upon running some tests with the client application, you should notice that the .NET remoting code processes faster than the Web services code. In this example, you should be able to produce a performance measurement demonstrating that the remoting code using binary formatting is approximately two times faster than the Web services code for 250 test cycles. These samples were tested with two PIII 833-MHz computers, both running Windows XP, equipped with 256 MB of RAM and connected over a standard 100-megabit network. While your specific results can vary based on your system configuration used for the comparison, the remoting example will always be faster. This happens because the .NET remoting client uses the binary formatter over HTTP, while the Web services communication is based on SOAP over HTTP.

It's safe to presume in this case that the .NET remoting client is much more efficient over the wire than its Web services counterpart. However, that isn't the whole story. If you change the formatter element's ref attribute in the client configuration from binary to soap, the .NET remoting client still performs faster. This is due to the .NET remoting system's internals and the efficiency of the channels and formatter sinks, both of which are key to the plumbing supporting remoting in the .NET Framework.

Both the .NET remoting and ASP.NET Web services architectures provide a suitable framework for developing distributed applications. For applications that require interoperability and must function over public networks, Web services are probably the best bet. For those that require communications with other .NET components and where performance is a key priority, .NET remoting can prove advantageous.

About the Author
Randy Holloway is the founder of Winformation Systems, a technology consulting and training initiative specializing in developing enterprise systems in the Windows environment and Web services technologies. Randy speaks on technology-related topics and writes for publications including XML & Web Services Magazine, Windows & .NET Magazine, and VSM. Contact Randy at .