Channels ▼
RSS

Mobile

Remoting in .NET Framework 2.0


November, 2005: Remoting in .NET Framework 2.0

Enhancing interapplication and interprocess communication

Vikram Srivatsa is a software designer working for Hewlett-Packard in Bangalore, India. Vikram holds an engineering degree in computer science and is also an MCSD for .NET. Vikram can be reached at vikram404@gmail.com.


The .NET Framework 2.0 is currently in its beta stage. The new version of the Framework offers various new features such as .NET Generics and support for 64-bit technology. At the same time, there have been updates to some of the existing components of the Framework, such as .NET Remoting and ADO.NET.

This article will focus on the updates that have been made to .NET Remoting in Version 2.0 of the Framework along with a discussion on the future direction of this technology. This article is based on the February 2005 Community Technology Preview (CTP) of .NET Framework 2.0—specifically Version 2.0.50110. As of that version, some of the features I discuss in this article work, and some do not yet, and will require a later beta release of the Framework. I have made note of this where appropriate throughout the article.

Features discussed in this article may or may not be included in the final shipping version of the Framework.

.NET Remoting: Background

.NET Remoting is a communication mechanism that can be used for communication between objects within the same process, between different processes on the same machine, and also between different processes separated by machine boundaries.

The first scenario of communication between objects within the same process refers to communication between multiple application domains, which is referred to as cross-AppDomain communication. In .NET, an application domain represents an isolated environment within the same process, and a single process can contain multiple application domains. Although the term is not strictly accurate, AppDomain is sometimes referred to as a "miniprocess" or a "lightweight process" for convenience in understanding.

The second scenario refers to a situation where communication needs to take place between two separate processes on the same machine, which is termed cross-process communication or interprocess communication. In this scenario, one of the communicating processes acts as a remoting server and the other acts as a client. The remoting server hosts the objects that are to be remoted. A remoting host can be a console application, windows application, windows service, or ASP.NET-based web application hosted in IIS.

The third scenario is similar to the second, with the addition of a machine boundary; that is, communication between two processes that are running on two separate machines. However, the important thing to note is that .NET Remoting is a Microsoft proprietary standard; hence, for remoting to work, both the machines should have the .NET Framework installed on them. Essentially, this means that .NET Remoting provides communication between machines in a homogenous environment.

New .NET Remoting Features in .NET Framework 2.0

The main enhancements that have been made in .NET Remoting and remoting-related technologies are:

  1. A new channel: IpcChannel.
  2. Enhancements to TcpChannel and HttpChannel.
  3. Version-Tolerant Serialization (VTS).
  4. Binary serialization for the Dataset class.
  5. Support for generic types.

IpcChannel

In simple terms, a channel is the "pipe" that is used to move the data. Versions of the .NET Framework before 2.0 offer channels based upon TCP and HTTP protocols. IpcChannel is a channel specifically optimized for communication between two processes residing on the same machine. (IPC stands for interprocess communication.) This channel bypasses the network layer because both processes are residing on the same machine and uses the Windows interprocess communication (IPC) system to transport the data between application domains.

Figure 1 shows the channels available in the .NET Framework, along with the .NET Framework versions on which the channels are supported. IpcChannel only supports a single-machine scenario and offers better performance compared to TcpChannel and HttpChannel when the communication is taking place between application domains on the same machine. In fact, if TcpChannel or HttpChannel were to be used in a single-machine remoting scenario, it would be necessary to set up a loopback adapter on the machine to simulate the existence of a network. IpcChannel makes communication between processes on a single machine convenient, eliminating the need for configurations such as loopback adapters.

IpcChannel also supports authorization at the channel level. It is possible to specify a particular windows group to IpcChannel and restrict access to the channel based on the group. This makes it possible to leverage the underlying windows security mechanisms without writing custom code to validate and authenticate users. It is possible to specify the authorization restrictions on IpcChannel by making use of the authorizedGroup property available on the channel.

The code snippet shows a section of a remoting configuration file and the use of the authorizedGroup property:

<channel ref="ipc" portName="MyRemoting" 
			     authorizedGroup="MyAppUsers">
  <serverProviders>
       <formatter ref="binary" /> 
  </serverProviders>
</channel>

Enhancements to TcpChannel and HttpChannel

A few enhancements have been added to TcpChannel and HttpChannel. It is possible to secure messages traveling on TcpChannel/HttpChannel by means of setting a few properties on the client- and server-side configuration files. This makes it easy to upgrade a nonsecure TcpChannel/HttpChannel based on 1.0/1.1 to a secure TcpChannel/HttpChannel. The settings are applicable to both the client and server side of the remoting application. I'll examine the server-side configuration first.

Two additional properties can now be set on TcpChannel/ HttpChannel: the secure property and the impersonate property. A sample section from a server-side remoting configuration file for a TcpChannel is shown here:

<channels>
  <channel ref="tcp" secure="true" port="800"
				    impersonate="true" />
</channels>

On the client side, we have two properties: the secure property and the tokenImpersonationLevel property. A sample section from a client-side remoting configuration file is shown here:

<system.runtime.remoting>
  <application>
     <channels>
  <channel ref="tcp" secure="true" 
		   tokenImpersonationLevel="impersonation"/>  
     </channels>      
  </application>
</system.runtime.remoting>

By setting the secure property to true on the client and server side, we are essentially securing the channel. This means that the data being transported on the channel is encrypted and signed. Additionally, the identity of the caller is also made available on the server when this property is set to true.

The second property is the impersonate property on the server side and the corresponding tokenImpersonationLevel property on the client side. Setting these properties allows for impersonation. That is, it is possible to run the method on the server as the identity associated with the caller. This makes it possible to utilize the already existing Windows users and define the security based on the Windows-based accounts.

Another feature specific to TcpChannel that will be included in the final release of the .NET Framework 2.0 is a way to control the socket cache. This was a major drawback in TcpChannel in the earlier version of the Framework because TcpChannel had socket affinity. This meant that network load balancing (NLB) would not work with TcpChannel. By being able to control the TCP socket cache, TcpChannel will finally support NLB. NLB has been well supported on HttpChannel since Version 1.0 of the .NET Framework.

The control over the cache is achieved by using two properties that can be added to the configuration of a channel. These are socketCacheTimeout, which specifies the time duration for timeout of the cache, and socketCachePolicy, which determines whether the time specified by socketCacheTimeout is to be measured from the time a socket was last used or from the time a socket was created.

Setting socketCacheTimeout to zero means that a new connection will be made each time, and this enables load balancing to work correctly.

The following code snippet shows a section of the sample configuration file for configuring the TcpChannel socket cache:

Server Side Configuration Settings
<channels>
  <channel ref="tcp" port="800" 
    socketCacheTimeout="0" 
    socketCachePolicy="absoluteTime-
    out"/>
</channels>

NOTE: The features discussed in this section do not work in the February 2005 CTP release of .NET Framework 2.0 and people interested in trying out this feature need to wait for the next beta release.

Version-Tolerant Serialization (VTS)

Serialization is the process of converting the state of an object so that it can be transported or persisted and then recreated when required. In .NET Framework 1.0/1.1, only the exact versions of the types were allowed to be serialized/deserialized when a type participated in .NET Remoting.

This limitation can be overcome by making use of the ISerializable interface to define a custom serialization mechanism. However, this decision would have to be made at an early stage and the initial version itself would need to have been built making use of ISerializable. Another issue with ISerializable has to do with inheritance hierarchies—every class in the hierarchy would need to implement ISerializable for this approach to be used.

.NET Framework 2.0 provides a much simpler approach to handle the problem of versioning of types that are used in .NET Remoting without having to implement the ISerializable interface. .NET Framework 2.0 has more version-tolerant features in the serialization infrastructure to make it more flexible and to support multiple versions of the type. This is useful in scenarios where new features are added to a type over a period of time. In such cases in the current version of the Framework, if the new type were to be deployed on the server, every client connecting to the server would also need to be updated. This problem can be overcome in .NET Framework 2.0 by making use of version-tolerant serialization.

In usual cases, the upgrade to a type takes the form of new properties being added to it, which results in missing data in the older versions. VTS allows for missing data to be handled by providing certain attributes that the developer can use on the new version of the type. The formatter classes have been updated to handle the information passed on by these attributes so that the deserialization continues to work in spite of some missing data.

The attribute OptionalField has been provided to mark a new property as optional to the type. Marking a field as optional solves the problem from the perspective of an older version of the client. However, the server would still need to have specific processing to handle this missing data. This has been achieved by providing four additional attributes, which correspond to the four stages involved in the serialization/deserialization process implemented in the .NET Framework. The four attributes and corresponding methods are shown in Table 1.

Each of the methods mentioned in the table needs to be decorated with the corresponding attributes mentioned. These methods will then act as hooks where the developer can set default values or any special handling for the data that is missing so that the processing on the server can proceed smoothly. The version-tolerant serialization is not supported on SOAPFormatter—Microsoft is considering deprecating the SOAPFormatter and, hence, VTS is supported only on the binary formatter.

Let's take a look at a code sample for this feature. Consider a common interface (contract) shared between a remoting client and a server. The interface is as shown in this code snippet:

public interface IRemotingInterface
{
    void ProcessMessage(ref string strValue, 
		        ref RemoteMessage objRemoteMessage);   
}

From this, we see that a custom object called RemoteMessage is being sent across the wire as part of remoting. (Of course, we would need to have a class on the server that would implement this interface and a client calling that object—but we will not focus on those aspects because the focus is to explain this feature using the custom object that is being used in remoting.)

Let's assume the RemoteMessage class has two. The detailed implementation of the class is shown in Listing 1.

In a later revision of the same class, we decide to add a new property, which we'll call MyNewProperty. In the normal scenario, remoting would fail because the object being remoted has undergone change, in terms of a new property being added to it. In order to overcome this issue, we use the OptionalField attribute; this is shown in Listing 2.

By adding the attribute, we have solved the problem for the client, which is only aware of the previous version. However, there are still some issues on the server because the data that was to be present in MyNewProperty is still missing. In order to handle this situation on the server, we make use of the other four methods with their corresponding attributes discussed earlier. The complete class now looks like Listing 3 (available at http://www.cuj.com/code/).

The four methods along with the attributes act as hooks where we can set the default value for the data. In the aforementioned sample, we have used the DeSerializing and the DeSerialized methods. In the DeSerializing method, we set an initialization value of "NotSpecified" to the newly added property. If the client actually supplied data, the initialization value would get overwritten by the data supplied by the client; if not, the value would still remain. After deserializing, the flow proceeds to the DeSerialized method. Here we compare values, and if the data has not been specified, we set the default value. (We can determine this by looking at the value of the property—if it is the same as the initialization value specified in the DeSerializing method, it implies that a value was not supplied.) This enables processing on the server side to proceed without any errors.

Binary Serialization for the Dataset Class

Binary Serialization is a much awaited enhancement to the Dataset class. In Version 1.0/1.1, the Dataset class was serializable but only supported XML format of serialization, irrespective of whether the formatter used was a binary formatter or a SOAP formatter. XML formatting, while more readable, takes up much more bandwidth than binary formatting.

A more efficient mechanism of serialization can be achieved by means of a simple property setting on the Dataset object. Dataset now exposes a property by the name RemotingFormat, which represents the serialization format to be used when the Dataset object participates in .NET Remoting. This can be set to either Xml or Binary. The default value is Xml. The following code snippet demonstrates this feature:

DataSet dsetData = new DataSet();
dsetData.RemotingFormat = SerializationFormat.Binary;

Support for Generic Types

.NET Framework 2.0 supports generics, and it is possible for generic types to participate in .NET Remoting. This is not supported on the SOAPFormatter—Microsoft is considering deprecating the SOAPFormatter; hence, remoting for generic types is supported only on the binary formatter.

Future Directions

The future of .NET Remoting technology itself has been questioned recently because Microsoft has announced that with the next wave of technologies (which Microsoft has termed "Longhorn" and is now officially called "Vista") the communication mechanism will be based on a new technology called "Windows Communication Foundation" (WCF), which is also known as "Indigo." So, does .NET Remoting have a future?

The answer to this is "Yes," but it could possibly be a short future. The best practice for now is to use .NET Remoting only if the scenario warrants its usage, but otherwise, to make use of web services. This is because migrating applications based on web services to WCF will be much simpler than migrating those based on .NET Remoting. Also, beyond .NET Framework 2.0, Microsoft does not intend to make new feature additions to the .NET Remoting subsystem, but the technology as such will still be supported. This means that the de facto option for communication will be WCF.

Windows Communication Foundation is a communication subsystem that enables distributed applications to communicate using a unified messaging system and will be introduced as a new namespace called System.Messaging. This technology will be made available as an add-on to Windows XP and Windows Server 2003. The official statement from Microsoft says ".NET Remoting will be deprecated once WCF is released."

So, the advice for now is, if you already have a heavy investment in .NET Remoting in a Version 1.0/1.1 application, then upgrading to .NET Framework 2.0 will make it possible to utilize a set of new features that can be added very easily to the existing application.

Additionally, .NET Remoting will remain the de facto standard for cross-application domain communication within the same process. In fact, the .NET Framework also makes use of .NET Remoting internally whenever there is a need for cross-application domain communication.

However, if you are building a new application, then .NET Remoting is recommended only if you intend to make use of custom transports or custom wire formats, as the channel and message infrastructures provided by the Remoting subsystem can be extended and customized. In such scenarios, it is strongly recommended to wrap the communication layer separately as a pluggable component that can be replaced in its entirety when the new WCF-based technologies arrive.

Useful Links

Visual Studio 2005 Launch Date; http://www.microsoft.com/presspass/ press/2005/jun05/TechEd2005Day2PR.mspx.

Visual Sutdio 2005 Beta 2 Go-Live License; http://lab.msdn .microsoft.com/vs2005/golive/.

Visual Studio 2005 update from Somasegar; http://blogs.msdn.com/ somasegar/archive/2005/08/22/451026.aspx.

CUJ


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video