An Introduction to Microsoft .NET Remoting Framework

 

Paddy Srinivasan
Microsoft Corporation

Summary: This article explains the fundamentals of the Microsoft .NET Remoting Framework. In addition to describing the main components that make up the .NET Remoting Framework, this document describes different scenarios in which .NET Remoting could be used to communicate with distributed objects. (11 printed pages)

Note This article includes updated Beta 2 code.

Contents

Introduction
.NET Remoting Objects
Hosting .NET Remoting Objects
.NET Remoting Metadata and Configuration files
.NET Remoting Scenarios
Conclusion
Further Reading

Introduction

Microsoft® .NET Remoting provides a rich and extensible framework for objects living in different AppDomains, in different processes, and in different machines to communicate with each other seamlessly. .NET Remoting offers a powerful yet simple programming model and runtime support for making these interactions transparent. In this article we will take a look at the different building blocks of the Remoting architecture, as well as explore some of the common scenarios in which .NET Remoting can be leveraged. For an overview of .NET Remoting, first read the article Microsoft .NET Remoting: A Technical Overview.

.NET Remoting Objects

There are three types of objects that can be configured to serve as .NET remote objects. You can choose the type of object depending on the requirement of your application. This section explains the following objects in detail:

  • Single Call
    Single Call objects service one and only one request coming in. Single Call objects are useful in scenarios where the objects are required to do a finite amount of work. Single Call objects are usually not required to store state information, and they cannot hold state information between method calls. However, Single Call objects can be configured in a load-balanced fashion.
  • **Singleton Objects
    **Singleton objects are those objects that service multiple clients and hence share data by storing state information between client invocations. They are useful in cases in which data needs to be shared explicitly between clients and also in which the overhead of creating and maintaining objects is substantial.
  • **Client-Activated Objects (CAO)
    **Client-activated objects (CAO) are server-side objects that are activated upon request from the client. This way of activating server objects is very similar to the classic COM coclass activation. When the client submits a request for a server object using "new" operator, an activation request message is sent to the remote application. The server then creates an instance of the requested class and returns an ObjRef back to the client application that invoked it. A proxy is then created on the client side using the ObjRef. The client's method calls will be executed on the proxy. Client-activated objects can store state information between method calls for its specific client and not across different client objects. Each invocation of "new" returns a proxy to an independent instance of the server type.

Passing Objects Using .NET Remoting

In .NET Remoting, objects can be passed from one application to another in the following ways:

  1. As parameters in method calls

    Example: public int myRemoteMethod (MyRemoteObject myObj)

  2. Return Value of method calls

    Example: public MyRemoteObject myRemoteMethod(String myString)

  3. Values resulting from property or field access of a .NET component

    Example: myObj.myNestedObject

For objects that are Marshal By Value (MBV), a complete copy of the object is made when the object is passed from one application to another.

For objects that are Marshal By Reference (MBR), a reference to the object is made when passed from one application to another. When the object reference (ObjRef) arrives in the remote application, it is turned into a "proxy" back to the original object.

Sample Code for a Simple .NET Remoting Server Object

using System;
using System.Runtime.Remoting;
namespace myRemoteService
{
    // Well Known Web Service object
    public class myRemoteObject : MarshalByRefObject
    {
        // Method myRemoteMethod
        public String myRemoteMethod(String s) 
        {
         return "Hello World";
        }
    }
}

Sample Client Code To Access This Object

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using myRemoteService;
public class Client
{
    public static int Main(string[] args)
    {
        ChannelServices.RegisterChannel(new HttpChannel());
      // Create an instance of a myRemoteObject class 
   myRemoteObject myObj = ( myRemoteObject)Activator.GetObject(typeof(myRemoteObject),
            "http://myHost:7021/host/myRemoteObject.soap");
      myObj. myRemoteMethod ("Hello World");
        return 0;
    }
}

Leased Based Lifetime

For objects that have object references that are transported outside the application, a lease is created. The lease has a lease time; when the lease reaches zero it expires and the object is disconnected from the .NET Remoting Framework. Once all the references to the object within the AppDomain have been freed, the object will be collected when the next garbage collection occurs. The lease controls the lifetime of the object.

While objects have a default Lease period, there are many ways to extend the lease period to keep the object alive in case the client wants to maintain state in the same server object.

  1. The server object can set its lease time to infinity, which instructs Remoting not to collect it during garbage collection cycles.
  2. The client can call the RemotingServices.GetLifetimeService method to get the lease of the server object from the lease manager of the AppDomain. From the Lease object the client can then call the Lease.Renew method to extend the lease.
  3. The client can register a sponsor for the specific lease with the lease manager of the AppDomain. When the remote object's lease expires, the lease manager calls back to the sponsor to request a lease renewal.
  4. If the ILease::RenewOnCallTime property is set, then each call to the remote object renews the lease by the amount of time specified by the RenewOnCallTime property.
  Single Call/Singleton Objects Client-Activated Objects
Client side- activation code (Code required on the client side)

For more information see the section on configuration files

a) Activator.GetObject()

b) new() with CFG file

Client's CFG file references the URL:

Foo= https://localhost:80/ObjectZone/Foo.soap

a) Activator.CreateInstance()

b) new() with CFG file

Client's CFG file references the URL. For example


https://localhost:80/ObjectZone

Activation of the server object No activation message is sent over the network until the first method call is made. Activation message is sent to the server machine when the client creates the object and a proxy is created on the client side. Constructors with parameters are supported.
Lifetime of the server object Lifetime is dictated by the configuration on the server. Could be either SingleCall or Singleton. Singleton objects are also subject to lifetime management. Lifetime is the earlier of these two events:

a) Lease expires

b) When the client loses its reference on the server object

Server side registration a) Use configuration file to specify the type (SingleCall or Singleton).

b) Use RegisterWellKnownServiceType() api to register the type.

Use configuration file to export the client-activated object.

For more information see the section on configuration files.

Advantages of the models a) Clients can be compiled against server component's base class or interface definition Common Language Runtime metadata.

b) Useful to perform finite operations on the server side.

c) Single call objects can be easily deployed in a Load Balanced system, as they don't hold state.

d) Singleton Objects can maintain state information across client objects.

a) Classic COM "coclass" like invocation of the server object.

b) Gives clients more flexibility to govern the server object's lifetime.

c) Client can pass constructor parameters to the created object.

d) Server Objects can hold state for its specific client between method calls.

Hosting .NET Remoting Objects

.NET Remoting objects can be hosted in:

  1. **Managed Executable
    **NET Remoting objects can be hosted in any regular .NET EXE or a managed Service.

  2. **IIS
    **Remoting objects can be hosted in Internet Information Server (IIS). By default, Remoting objects hosted in IIS receive messages through the HTTP channel. For hosting Remoting objects under the IIS, a virtual root has to be created and a "remoting.config" file has to be copied to it. The executable or DLL containing the remote object should be placed in the bin directory under the directory the IIS root points to. It is important to note that the IIS root name should be the same as the Application name specified in the configuration files. The Remoting configuration file is automatically loaded when the first message arrives in the application. This way .NET Remoting Objects can be exposed as Web Services.

    Sample Remoting.cfg file:

    <configuration>
      <system.runtime.remoting>
        <application name="RemotingHello">
    
          <service>
            <wellknown mode="SingleCall" 
                       type="Hello.HelloService, Hello" 
                       objectUri="HelloService.soap" />
          </service>
    
          <channels>
            <channel port="8000" 
    type="System.Runtime.Remoting.Channels.Http.HttpChannel, 
    System.Runtime.Remoting" />
          </channels>
    
        </application>
      </system.runtime.remoting>
    </configuration>
    
  3. **.NET Component Services
    **NET Remoting objects can be hosted in the .NET component services infrastructure to take advantage of the various COM+ services like Transactions, JIT, and Object pooling.

    For more information, see Microsoft .NET Framework Component Services, Part 1.

Channel Services (System.Runtime.Remoting.Channels)

.NET Applications and AppDomains communicate among each other using messages. .NET Channel Services provides the underlying transport mechanism for this communication.

The .NET Framework supplies the HTTP and TCP channels but third parties can write and plug in their own channels. The HTTP channel use SOAP by default to communicate, whereas the TCP channel uses Binary payload by default.

The Channel Services are pluggable (using IChannel) using custom channels that can be written to integrate heterogeneous applications.

Sample Code To Load the Channel Services

public class myRemotingObj
{
    HttpChannel httpChannel;
    TcpChannel tcpChannel;
    public void myRemotingMethod()
    {
httpChannel =  new HttpChannel();
tcpChannel  =  new TcpChannel();
        ChannelServices.RegisterChannel(httpChannel);
// Register the HTTP Channel 
        ChannelServices.RegisterChannel(tcpChannel);
// Register the TCP Channel  


    }
} 

Serialization Formatters (System.Runtime.Serialization.Formatters)

.NET serialization formatters encode and decode the messages between .NET Applications and AppDomains. There are two native formatters in the .NET runtime, namely Binary(System.Runtime.Serialization.Formatters.Binary) and SOAP (System.Runtime.Serialization.Formatters.Soap).

The Serialization Formatters are pluggable by implementing the IRemotingFormatter interface and plugging it into the Channel mentioned above. This process, which will be discussed in a later section of this document, offers the flexibility to choose the combination of a Channel and a Formatter that best suits your applications.

Example: You can have HTTP channel using the Binary formatter that serializes binary data and also TCP channel using SOAP formatting.

Remoting Contexts

A context is a boundary that contains objects that share common runtime properties. Some examples of context attributes are synchronization and thread affinity. When a .NET object is activated the runtime checks if the current context is compatible and if not, a new context is created. A context can have multiple objects running in it at the same time and an AppDomain can have multiple contexts in it.

Any call from an object in one context to an object in another context will go through a context proxy and be affected by the policy that the combined context properties enforce. The context of a new object is generally chosen based on metadata attributes on the class.

Classes that can be bound to a context are called context-bound classes. Context-bound classes can be attributed with specialized custom attributes known as context attributes. Context attributes are completely extensible and you can create and attach these attributes to your class. Objects that are bound to a context derive from System.ContextBoundObject.

.NET Remoting Metadata and Configuration files

Metadata

The .NET Framework uses metadata and assemblies to store information about components, enabling cross-language programming. .NET Remoting uses metadata to dynamically create proxy objects. The proxy objects that are created at the client side have the same members as the original class. But the implementation of the proxy object just forwards all requests through the .NET Remoting runtime to the original object. The serialization formatter uses metadata to convert method calls to payload stream and back.

The client can obtain the metadata information required to access the remote object in the following ways:

  1. The .NET Assembly of the server object—the server object can create a metadata assembly and distribute it to the clients. The client object can reference the assembly while compiling the client object. This is very useful in closed scenarios where the client and server are managed components.
  2. The Remoting object can provide a WSDL (see the Web Services Description Language (WSDL) 1.1) file that describes the object and its methods. Any client that can read and generate SOAP requests corresponding to the WSDL file can invoke this object and communicate to it using SOAP. .NET Remoting Server objects can use the SOAPSUDS.EXE tool, which ships with the .NET SDK, to generate WSDL files that can serve as metadata. This is useful when an organization wants to provide a public service that any client can access and use.
  3. .NET clients can use the SOAPSUDS utility to download the XML schema from the server (generated on the server) to generate source files or an assembly that contains only metadata, no code. The source files can optionally be compiled into the client application. This method is useful in a multi-tier application in which objects from one tier want to access remote objects in another tier.

Configuration files

Configuration files (.config files) are used to specify the various Remoting specific information for a given object. Usually each AppDomain has its own config file. Using config files helps in achieving location transparency. Details specified in the config files can also be done programmatically. The main advantage of using config files is that they separate the configuration information transparent to the client code so that future changes can be made just by changing the config file as opposed to editing and recompiling the source file. Configuration files are used both by .NET Remoting client and server objects.

A typical config file includes the following, among other, information:

  1. Host application information
  2. Name of the objects
  3. URI of the objects
  4. Channels being registered (Multiple channels can be registered at the same time)
  5. Lease Time information for Server Objects

The following is a sample configuration file (please note that this format might change to XML in future releases):

<configuration>
  <system.runtime.remoting>
    <application name="HelloNew">

      <lifetime leaseTime="20ms" sponsorshipTimeout="20ms" 
renewOnCallTime="20ms" />  

      <client url="https://localhost:8000/RemotingHello">
        <wellknown type="Hello.HelloService, MyHello" 
      url="https://localhost:8000/RemotingHello/HelloService.soap" />
        <activated type="Hello.AddService, MyHello"/>
      </client>
      
      <channels>
        <channel port="8001" 
      type="System.Runtime.Remoting.Channels.Http.HttpChannel, 
      System.Runtime.Remoting" />
      </channels>
      
    </application>
  </system.runtime.remoting>
</configuration>

.NET Remoting Scenarios

Now that we're equipped with an understanding of how .NET Remoting works, let's look at various scenarios and explore how .NET Remoting can be best employed in each of them. The following table contains a list of possible client-server combinations along with the underlying protocol and payload it uses by default. Please keep in mind that .NET Remoting Framework is extensible and it is possible to write your own communication channel and serialization formatter.

Client Server Payload Protocol
.NET Component .NET Component SOAP/XML http
.NET Component .NET Component Binary TCP
Managed/Unmanaged .NET Web Services SOAP/XML http
.NET Component Unmanaged Classic COM Component NDR (Network Data Representation) DCOM
Unmanaged Classic COM Component .NET Component NDR DCOM

ANY Client <-> .NET Using HTTP-SOAP

A Web Service is a URL-addressable resource that programmatically returns information to clients who want to use it. Clients can use Web Services without worrying about their implementation details. Web Services use well-defined interfaces called contracts that are described using a Web Services Description Language (WSDL) file. For more information on WSDL, please see Web Services Description Language (WSDL) 1.0.

.NET Remoting objects can be exposed as a Web Service by hosting them in IIS. Any client that can consume a WSDL file can make SOAP calls to the remote object as per the contract specified in the WSDL file. IIS routes the request to the appropriate object using ISAPI extensions. Thus the Remoting object can function as a Web Service object and leverage the rich .NET Framework infrastructure. This configuration is useful in cases where you would like your objects to be accessed by programs from different platforms/ environment. For more information on Web Services please see The Programmable Web: Web Services Provides Building Blocks for the Microsoft .NET Framework. This configuration makes it easy for clients to access your .NET objects over the firewall.

Figure 1. Example of a client invoking a remoting object's Web Service through HTTP-SOAP

.NET<->.NET Using SOAP-HTTP Channel

The HTTP channel uses the SOAP formatter by default and hence can be used in scenarios where clients will access the objects over the Internet. Since this approach uses HTTP, accessing .NET objects remotely through a firewall is enabled by this configuration. Objects exposed in this way can easily be configured as Web Services Objects simply by hosting these objects in IIS, as explained in the previous section. Clients can then read the WSDL files of these objects to communicate with the Remote object using SOAP.

.NET<->.NET Using TCP Channel

The TCP Channel uses the binary formatter by default. This formatter serializes the data in binary form and uses raw sockets to transmit data across the network. This method is ideal if your object is deployed in a closed environment within the confines of a firewall. This approach is more optimized since it uses sockets to communicate binary data between objects. Using the TCP channel to expose your object gives you the advantage of low overhead in closed environments. This approach cannot be used over the Internet because of firewall and configuration issues.

Figure 2. Example of a client invoking a Remoting object across machine boundaries using the TCP channel

.NET <-> Unmanaged COM Component <-> .NET

It is possible to call Unmanaged Classic COM components through COM Interop Services. When the .NET Remoting client object creates an instance of a COM object, the object is exposed through a runtime callable wrapper (RCW) that acts as a proxy for the real unmanaged object. These wrappers appear to be just like any other managed class to the .NET client, but in actuality they just marshal calls between managed (.NET) and unmanaged (COM) code.

Similarly you can expose a .NET Remoting server object to classic COM clients. When a COM client creates an instance of the .NET object, the object is exposed through a COM callable wrapper (CCW) that acts as a proxy for the real managed object.

Both these scenarios use DCOM for communication. This interoperability is very handy in scenarios where there is a heterogeneous mix of Classic COM and .NET components.

Conclusion

The Microsoft .NET Framework provides a powerful, extensible, and language-independent framework to develop robust and scalable distributed systems. The .NET Remoting Framework provides powerful ways to remote interaction depending on the requirement of the system. .NET Remoting integrates seamlessly with Web Services and provides a way to expose .NET objects for access across multiple platforms.

Further Reading