Home > Articles

.NET Remoting

  • Print
  • + Share This
This chapter is from the book

.NET Remoting Architecture

.NET remoting enables objects in different application domains to talk to each other. The real strength of remoting is in enabling the communication between objects when their application domains are separated across the network. In this case, remoting transparently handles details related to network communication.

Before I get into details, I'll first answer a basic question: How come remoting is able to establish cross-application domain communication when the application domains do not allow direct calls across their boundaries?

Remoting takes an indirect approach to application domain communication by creating proxy objects as shown in Figure 3.1. Both application domains communicate with each other by following these steps:

Figure 3.1Figure 3.1 In this simplified view of .NET remoting, you can see that client and server communicate indirectly through a proxy object.

  1. When a client object requests an instance of the server object, the remoting system at the client side instead creates a proxy of the server object. The proxy object lives at the client but behaves just like the remote object; this leaves the client with the impression that the server object is in the client's process.

  2. When the client object calls a method on the server object, the proxy passes the call information to the remoting system on the client. This remoting system in turn sends the call over the channel to the remoting system on the server.

  3. The remoting system on the server receives the call information and, on the basis of it, invokes the method on the actual object on the server (creating the object if necessary).

  4. The remoting system on the server collects the result of the method invocation and passes it through the channel to the remoting system on the client.

  5. The remoting system at the client receives the server's response and returns the results to the client object through the proxy.

The process of packaging and sending method calls among objects, across application boundaries, via serialization and deserialization, as shown in the preceding steps, is also known as marshaling.

Now that you have a basic idea of how .NET remoting works, it's time to get into the details. In the next few sections, I'll explain various key components and terminology of .NET remoting.

Object Marshaling

Remotable objects are the objects that can be marshaled across the application domains. In contrast, all other objects are known as non-remotable objects. There are two types of remotable objects:

  • Marshal-by-value (MBV) Objects—These objects are copied and passed out of the server application domain to the client application domain.

  • Marshal-by-reference (MBR) Objects—A proxy is used to access these objects on the client side. The clients hold just a reference to these objects.

Marshal-by-value Objects

MBV objects reside on the server. When a client invokes a method on the MBV object, the MBV object is serialized, transferred over the network, and restored on the client as an exact copy of the server-side object. Now, the MBV object is locally available and therefore any method calls to the object do not require any proxy object or marshaling.

The MBV objects can provide faster performance by reducing the network roundtrips, but in the case of large objects, the time taken to transfer the serialized object from server to the client can be very significant. Furthermore, the MBV objects do not provide the privilege of running the remote object in the server environment.

You can create an MBV object by declaring a class with the Serializable attribute. For example:

//define a MBV remoting object
[Serializable()]
public class MyMBVObject
{
  //... 
}

If a class needs to control its own serialization, it can do so by implementing the ISerializable interface as follows:

//define a MBV remoting object
[Serializable()]
public class MyMBVObject : ISerializable
{
  //...
  //Implement custom serialization here
  public void GetObjectData(
    SerializationInfo info, 
    StreamingContext context)
  {
    //...
  }
  //...
}

NOTE

The NonSerialized Attribute By default public and private fields of a class are serialized, if a Serializable attribute is applied to the class. If you do not want to serialize a specific field in a serializable class, apply the NonSerialized attribute on that field. For example, in the class Sample, although field1 and field2 are serialized, field3 is not serialized because of the NonSerialized attribute.

[Serializable()]   
public class Sample 
{
  public int field1;
  public string field2;
  // A field that is not serialized.
  [NonSerialized()] 
  public string field3;
.
.
.
}

Marshal-by-reference Objects

The MBR objects are remote objects. They always reside on the server and all methods invoked on these objects are executed at the server side. The client communicates with the MBR object on the server by using a local proxy object that holds the reference to the MBR object.

Although the use of MBR objects increases the number of network roundtrips, they are a likely choice when the objects are prohibitively large or when the functionality of the object is available only in the server environment on which it is created.

You can create an MBR object by deriving the MBR class from the System.MarshalByRefObject class. For example:

//define a MBR remoting object
public class MyMBRObject : MarshalByRefObject
{
  //... 
}

Channels

Create and consume a .NET remoting object

  • Select a channel protocol and a formatter. Channel protocols include TCP and HTTP. Formatters include SOAP and binary.

Channels are the objects that transport messages across remoting boundaries such as application domains, processes, and computers. When a client calls a method on the remote objects, the details of the method call—such as parameters and so on—are transported to the remote object through a channel. Any results returned from the remote object are communicated back to the client again through the same channel.

The .NET remoting framework ensures that before a remote object can be called, it has registered at least one channel with the remoting system on the server. Similarly, the client object should specify a channel before it can communicate with a remote object. If the remote object offers more than one channel, the client can connect by using the channel that best suits its requirements.

A channel has two end points. The channel object at the receiving end of a channel (the server) listens to a particular protocol through the specified port number, whereas the channel object at the sending end of the channel (the client) sends information to the receiving end by using the protocol and port number specified by the channel object on the receiving end.

TIP

Port Numbers Should Be Unique on a Machine Each channel is uniquely associated with a TCP/IP port number. Ports are machine-wide resources; therefore, you cannot register a channel that listens on a port number that is already in use by some other channel on the same machine.

To participate in the .NET remoting framework, the channel object at the receiving end must implement the IChannelReceiver interface, whereas the channel object at the sending end must implement the IChannelSender interface.

The .NET Framework provides implementations for HTTP (Hypertext Transmission Protocol) and TCP (Transmission Control Protocol) channels. If you want to use a different protocol, you can define your own channel by implementing the IChannelReceiver and IChannelSender interfaces.

HTTP Channels

The HTTP channels use HTTP for establishing communication between the two ends. These channels are implemented through the classes of the System.Runtime.Remoting.Channels.Http namespace, as shown in Table 3.1.

Table 3.1: The HTTP Channel Classes

Class

Implements

Purpose

HttpServerChannel

IChannelReceiver

An implementation for a server channel that uses the HTTP to receive messages.

HttpClientChannel

IChannelSender

An implementation for a client channel that uses the HTTP to send messages.

HttpChannel

IChannelReceiver and IChannelSender

An implementation of a combined channel that provides the functionality of both the HttpServerChannel and the HttpClientChannel classes.


The following code example shows how to register a sender-receiver HTTP channel on port 1234:

using System; 
using System.Runtime.Remoting.Channels; 
using System.Runtime.Remoting.Channels.Http; 
//... 
 HttpChannel channel = new HttpChannel(1234); 
 ChannelServices.RegisterChannel(channel); 
//...

The ChannelServices class used in the code provides various remoting-related services. One of its static methods is RegisterChannel(), which helps in registering a channel with the remoting framework.

TCP Channels

The TCP channel uses TCP for establishing communication between the two ends. The TCP channel is implemented through various classes of the System.Runtime.Remoting.Channels.Tcp namespace, as shown in Table 3.2.

Table 3.2: The TCP Channel Classes

Class

Implements

Purpose

TcpServerChannel

IChannelReceiver

An implementation for a server channel that uses the TCP to receive messages.

TcpClientChanel

IChannelSender

An implementation for a client channel that uses the TCP to send messages.

TcpChannel

IChannelReceiver and IChannelSender

An implementation of a combined channel that provides the functionality for both TcpServerChannel and TcpClientChannel classes.


The following code example shows how to register a sender-receiver TCP channel on port 1234:

using System; 
using System.Runtime.Remoting.Channels; 
using System.Runtime.Remoting.Channels.Tcp; 
//... 
 TcpChannel channel = new TcpChannel(1234); 
 ChannelServices.RegisterChannel(channel); 
//...

Choosing Between the HTTP and the TCP Channels

Table 3.3 helps you make a decision about which channel to use in a given scenario. In summary, you'll normally use the TCP channel within a low-risk intranet. For more wide-reach applications, using the HTTP channel makes more sense unless the application's efficiency requirements justify the cost of creating a customized security system.

TIP

Support for Security .NET remoting has no built-in support for security. It instead depends on the remoting hosts to provide security. The only built-in remoting host that provides security for remote objects is IIS. Therefore, any secured objects must be hosted in IIS.

Table 3.3: Choosing Between the HTTP Channel and the TCP Channel

Channel

Scope

Efficiency

Security

HttpChannel

Wide, using the HTTP channel enables you to host the objects on a robust HTTP server such as IIS. HTTP channels can be used over the Internet, because firewalls do not generally block HTTP communication.

Less, because HTTP is a bulky protocol and has lots of extra overhead.

More, because when remote objects are hosted in IIS, the HttpChannel can immediately take advantage of Secure Sockets Layer (SSL), Integrated Windows Authentication or Kerberos.

TcpChannel

Narrow, using the TCP channel over the Internet would require opening certain ports in the firewall and could lead to security breaches.

More, because TCP uses raw sockets to transmit data across the network.

Less, until you implement a custom security system using the classes provided in the System.Security namespace.


Formatters

Create and consume a .NET Remoting object

  • Select a channel protocol and a formatter. Channel protocols include TCP and HTTP. Formatters include SOAP and binary.

Formatters are the objects that are used to encode and serialize data into messages before they are transmitted over a channel. At the other end of the channel, when the messages are received, formatters decode and deserialize the messages.

To participate in the .NET remoting framework, the formatter classes must implement the IFormatter interface. The .NET Framework packages two formatter classes for common scenarios: the BinaryFormatter class and the SoapFormatter class. If you want to use a different formatter, you can define your own formatter class by implementing the IFormatter interface.

The SOAP Formatter

SOAP (Simple Object Access Protocol) is a simple, XML-based protocol for exchanging types and messages between applications. SOAP is an extensible and modular protocol; it is not bound to a particular transport mechanism such as HTTP or TCP.

The SOAP formatter is implemented in the SoapFormatter class of the System.Runtime.Serialization.Formatters.Soap namespace.

SOAP formatting is an ideal way of communicating between applications that use non-compatible architectures. However, SOAP is very verbose. SOAP messages require more bytes to represent the data as compared to the binary format.

The Binary Formatter

Unlike SOAP, the binary format used by the .NET Framework is proprietary and can be understood only within .NET applications. However, as compared to SOAP, the binary format of representing messages is very compact and efficient.

The binary formatter is implemented in the BinaryFormatter class of the System.Runtime.Serialization.Formatters.Binary namespace.

Channels and Formatters

The HTTP channel uses the SOAP formatter as its default formatter to transport messages to and from the remote objects. The HTTP channel uses SoapClientFormatterSinkProvider and SoapServerFormatterSinkProvider classes to serialize and deserialize messages through the SoapFormatter class. You can create industry-standard XML Web services when using SOAP formatter with the HTTP channel.

The TCP channel uses the binary format by default to transport messages to and from the remote object. The TCP channel uses BinaryClientFormatterSinkProvider and BinaryServerFormatterSinkProvider classes to serialize and deserialize messages through the BinaryFormatter class.

However, channels are configurable. You can configure the HTTP channel to use the binary formatter or a custom formatter rather than the SOAP formatter. Similarly, the TCP channel can be configured to use the SOAP formatter or a custom formatter rather than the binary formatter.

Figure 3.2 compares the various combinations of channels and formatters on the scale of efficiency and compatibility. You can use this information to decide which combination of channel and formatter you would chose in a given scenario.

Figure 3.2Figure 3.2 A TCP channel with a binary formatter provides maximum efficiency, whereas an HTTP channel with a SOAP formatter provides maximum interoperability.

REVIEW BREAK

  • .NET remoting enables objects in different application domains to talk to each other even when they are separated by applications, computers, or the network.

  • The process of packaging and sending method calls among the objects across the application boundaries via serialization and deserialization is called marshaling.

  • Marshal-by-value (MBV) and Marshal-by-reference (MBR) are the two types of remotable objects. MBV objects are copied to the client application domain from the server application domain, whereas only a reference to the MBR objects is maintained in the client application domain. A proxy object is created at the client side to interact with the MBR objects.

  • A channel is an object that transports messages across remoting boundaries such as application domains, processes, and computers. The .NET Framework provides implementations for HTTP and TCP channels to allow communication of messages over the HTTP and TCPs, respectively.

  • A channel has two end points. A channel at the receiving end, the server, listens for messages at a specified port number from a specific protocol, and a channel object at the sending end, the client, sends messages through the specified protocol at the specified port number.

  • Formatters are the objects that are used to serialize and deserialize data into messages before they are transmitted over a channel. You can format the messages in SOAP or the binary format with the help of SoapFormatter and BinaryFormatter classes in the FCL.

  • The default formatter for transporting messages to and from the remote objects for the HTTP channel is the SOAP formatter and for the TCP channel is the binary formatter.

Remote Object Activation

Between the two types of objects you have studied—the MBV objects and the MBR objects—only MBR objects can be activated remotely. No remote activation is needed in the case of MBV objects because the MBV object itself is transferred to the client side.

TIP

Remotable Members An MBR object can remote the following types of members:

Non-static public methods

Non-static public properties

Non-static public fields

Based on the activation mode, MBR objects are classified in the following two categories:

  • Server-activated objects

  • Client-activated objects

Server-Activated Objects

Server-activated objects (SAOs) are those remote objects whose lifetime is directly controlled by the server.

When a client requests an instance of a server-activated object, a proxy to the remote object is created in the client's application domain. The remote object is only instantiated (or activated) on the server when the client calls a method on the proxy object.

The server-activated objects provide limited flexibility because only their default (parameter-less) constructors can be used to instantiate them.

There are two possible activation modes for a server-activated object:

  • SingleCall activation mode

  • Singleton activation mode

NOTE

Well-Known Objects Remote objects activated in SingleCall or Singleton activation mode are also known as server-activated objects or well-known objects.

SingleCall Activation Mode

In the SingleCall activation mode, an object is instantiated for the sole purpose of responding to just one client request. After the request is fulfilled, the .NET remoting framework deletes the object and reclaims its memory.

Objects activated in the SingleCall mode are also known as stateless because the objects are created and destroyed with each client request and therefore do not maintain state across the requests. This behavior of the SingleCall mode accounts for greater server scalability as an object consumes server resources for only a small period, therefore allowing the server to allocate resources to other objects.

TIP

Load-Balancing and SingleCall Activation Sometimes to improve the overall efficiency of an application, the application may be hosted on multiple servers that share the incoming requests to it. In this case, a request can go to any of the available servers for processing. This scenario is called a load-balancing environment.

Because the SingleCall objects are stateless, it does not matter which server processes their requests. For this reason, SingleCall activation is ideally suited for load- balanced environments.

The SingleCall activation mode is a desired solution when

  • The overhead of creating an object is not significant.

  • The object is not required to maintain its state.

  • The server needs to support a large number of requests for the object.

  • The object needs to be supported in a load-balanced environment.

Scenarios that are often well suited for the SingleCall activation mode are those applications where the object is required by the client to do a small amount of work and then the object is no longer required. Some common examples include retrieving the inventory level for an item, displaying tracking information for a shipment, and so on.

Singleton Activation Mode

In the Singleton activation mode, there is at most one instance of the remote object, regardless of the number of clients accessing it.

A Singleton mode object can maintain state information across the method calls. Therefore, they are also sometimes known as stateful objects. The state maintained by the Singleton mode server-activated object is globally shared by all its clients.

A Singleton object does not exist on the server forever. Its lifetime is determined by the lifetime lease of the object. I'll discuss lifetime leases shortly in the section, "Lifetime Leases."

A Singleton object is a desired solution when

  • The overhead of creating an object is substantial.

  • The object is required to maintain its state over a prolonged period.

  • Several clients need to work on the shared state.

Singleton activation mode is useful in scenarios such as in a chat server where multiple clients talk to the same remote object and share data between one another.

Client-Activated Objects

Client-activated objects (CAOs) are those remote objects whose lifetime is directly controlled by the client. This is in direct contrast with SAOs, where the server, not the client, has complete control over objects' lifetimes.

Client-activated objects are instantiated on the server as soon as the client requests the object to be created. Unlike SAOs, CAOs do not delay object creation until the first method is called on the object.

You can use any of the available constructors of the remotable class to create a CAO. A typical CAO activation involves the following steps:

  1. When the client attempts to create an instance of the server object, an activation request message is sent to the remote server.

  2. The server then creates an instance of the requested class by using the specified constructor and returns an ObjRef object to the client application that invoked it. The ObjRef object contains all the required information to generate a proxy object that is capable of communicating with a remote object.

  3. The client uses the ObjRef object to create a proxy of the server object on the client side.

An instance of the CAO serves only the client that was responsible for its creation, and the CAO doesn't get discarded with each request. For this reason, a CAO can maintain state with each client that it is serving, but unlike Singleton SAOs, different CAOs cannot share a common state.

The lifetime of a CAO is determined by the lifetime leases. I'll talk more about this topic shortly in a section titled "Lifetime Leases."

A CAO is a desired solution when

  • Clients want to maintain a private session with the remote object.

  • Clients want to have more control over how the objects are created and how long they will live.

CAOs are useful in scenarios such as entering a complex purchase order where multiple roundtrips are involved and clients want to maintain their own private state with the remote object.

Comparing the Object Activation Techniques

Based on the discussions in the previous section, the various object activation techniques can be compared as shown in Figure 3.3.

Figure 3.3Figure 3.3 The SingleCall server activation offers maximum scalability, whereas the client activation offers maximum flexibility.

SingleCall server activation mode offers maximum scalability because the remote object occupies server resources for the minimum length of the time. This enables the server to allocate its resources between many clients.

On the other hand, the client activation of remote objects offers maximum flexibility because you have complete control over the construction and lifetime of the remote object.

Lifetime Leases

A lifetime lease is the period of time that a particular object shall be active in memory before the .NET framework deletes it and reclaims its memory. Both Singleton SAOs and CAOs use lifetime leases to determine how long they should continue to exist.

NOTE

Leases and Activation Mode Leases apply only to Singleton SAOs and CAOs. With SingleCall SAOs, objects are created and destroyed with each method call.

TIP

Custom and Infinite Lifetimes A remote object can choose to have a custom defined lifetime if the InitializeLifetimeService() method of the base class, MarshalByRefObject, is overridden. If the InitializeLifetimeService() method returns a null, the type tells the .NET remoting system that its instances are intended to have an infinite lifetime.

A lifetime lease is represented by an object that implements the ILease interface that is defined in the System.Runtime.Remoting.Lifetime namespace. Some of the important members of this interface are listed in Table 3.4.

Table 3.4: Important Members of the ILease Interface

Member Name

Type

Description

CurrentLeaseTime

Property

Gets the amount of time remaining on the lease before the object is marked for garbage collection.

InitialLeaseTime

Property

Gets or sets the initial time for the lease. If the object does not receive any method calls, it lives for only this period.

Register()

Method

Registers a sponsor for the lease.

Renew()

Method

Renews a lease for the specified time.

RenewOnCallTime

Property

Gets or sets the amount of time by which a call to the remote object will increase the CurrentLeaseTime.

SponsorshipTimeout

Property

Gets or sets the amount of time to wait for a sponsor to return with a lease renewal time.


Simply speaking, the lease works as follows:

  • When an object is created, the value of the InitialLeaseTime property (which is by default 5 minutes) is used to set its lifetime lease (CurrentLeaseTime).

  • Whenever the object receives a call, its CurrentLeaseTime is increased by the time specified by value of RenewOnCallTime property (which is by default 2 minutes).

  • The client can also renew a lease for a remote object by directly calling the ILease.Renew() method:

    ILease lease = (ILease)
        RemotingServices.GetLifetimeService(
        RemoteObject);
    TimeSpan expireTime = 
        lease.Renew(TimeSpan.FromSeconds(60)); 
  • When the value of CurrentLeaseTime reaches 0, the .NET Framework contacts any sponsors registered with the lease to check whether they are ready to sponsor a renewal of the lease of the object.

  • If the sponsor does not renew the object or the server cannot contact the sponsor within the duration specified by the SponsorshipTimeout property, then the object is marked for garbage collection.

Sponsors are the objects responsible for dynamically renewing an object's lease if its lease expires. Sponsors implement the ISponsor interface and are registered with the lease manager by calling the ILease.Register() method. When the lease for such an object expires, the lease manager calls the ISponsor.Renewal() method implemented by the sponsor objects to renew the lease time. For more information about sponsors, refer to the "Renewing Leases" topic in the .NET Framework Developer's Guide.

REVIEW BREAK

  • The MBR remotable objects can be activated in two modes: server-activated mode and client-activated mode.

  • Server-activated objects (SAOs) are those remote objects whose lifetime is directly controlled by the server.

  • You can activate SAOs in two ways: SingleCall (object is created for each client request) and Singleton (object is created once on the server and is shared by all clients).

  • The SingleCall activation mode provides the maximum scalability because it does not maintain any state and the object lives for the shortest duration possible.

  • CAOs are created for each client when the client requests that a remote object be created. These objects maintain state for each client with which they are associated.

  • The leased-based lifetime process determines how long Singleton SAOs and CAOs should exist.

  • + Share This
  • 🔖 Save To Your Account