Improved .NET Remoting, Part 1: Same-Box Communication

.NET remoting enables application communication. It is a generic system that different applications can use to communicate with one another. By exposing its objects to remote processes, .NET allows interprocess communication. The applications can be located on the same computer, different computers on the same network, or even computers across separate networks. Versions 1.0 and 1.1 of the .NET Framework provided TcpChannel and HttpChannel for communication. These channels required network communication regardless of where the applications were actually located relative to each other.

The Windows operating system features an interprocess communication system (commonly referred to as IPC). This communication method is designed for applications on the same computer to communicate and does not use network communication. Because IPC does not use network communication, the IPC channel is significantly faster than the TCP and HTTP channels for communication between app domains on the same computer. The System.Runtime.Remoting.Channels.Ipc is a new namespace in the pending release of the .NET Framework 2.0 that contains classes designed to use the IPC channel.

The remainder of this article covers the process of remoting and walks through the following example.

  1. Creating a remotable object
  2. Creating a server to expose the remotable object
  3. Creating a client to connect to the server and consume the object

All you need to follow along is a familiarity with remoting, which you can acquire by referring to a prior article on the topic.

Create a Remotable Object

A remotable object is an object that inherits from MarshalByRefObject. The following sample demonstrates a simple class to expose the omnipresent "hello world". This object exposes a single method (HelloWorld) that will return a string. Anything that is serializable can be returned from the method call.

Create a new C# class library project. Add a class called SampleObject and put in the following code:

using System;

namespace CodeGuru.RemotingSample
{
   /// <remarks>
   /// Sample object to demonstrate the use of .NET remoting and IPC.
   /// </remarks>
   public class SampleObject : MarshalByRefObject
   {
      /// <summary>
      /// Constructor
      /// </summary>
      public SampleObject()
      {
      }

      /// <summary>
      /// Return a hello message
      /// </summary>
      /// <returns>Hello world message</returns>
      public string HelloWorld()
      {
         return "Hello World!";
      }
   }
}

Compile the class to make sure you have everything correct.

Create a Server to Expose the Remotable Object via IPC

You need to create a server object that will act as a listener to accept remote object requests. If you were using the TCP or HTTP channels, you'd have to register the listener on a specific port number, but not so for IPC. You create an instance of the channel and then register it for use by clients through the ChannelServices, and then give it a name. The service can be registered as WellKnownObjectMode.SingleCall, which results in a new instance of the object for each client, or as WellKnownObjectMode.Singleton, which results in one instance of the object used for all clients.

Create a new C# console application project. Add a class called SampleRemotingServer and paste in the following code:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace CodeGuru.RemotingSample
{
   /// <remarks>
   /// Sample server to demonstrate the use of .NET remoting and IPC.
   /// </remarks>
   public class SampleRemotingServer
   {
      public static void Main()
      {
         // Create an instance of a channel
         IpcServerChannel serverChannel = new IpcServerChannel("hello");
         ChannelServices.RegisterChannel(serverChannel);

         // Register as an available service with the name HelloWorld
         RemotingConfiguration.RegisterWellKnownServiceType( \
         typeof(SampleObject),
         "HelloWorld",
         WellKnownObjectMode.Singleton );

         Console.WriteLine("Listening on {0}",
                           serverChannel.GetChannelUri());
         Console.WriteLine("Press the enter key to exit...");
         Console.ReadLine();
      }
   }
}

Add a reference to System.Runtime.Remoting in the project; otherwise, the IpcChannel and other related classes will not be found. In addition, add a reference to the project containing the SampleObject. Otherwise, the code will not compile because it won't know how to find a reference to SampleObject.

Improved .NET Remoting, Part 1: Same-Box Communication

Create an IPC Client to Use the Remotable Object

Now that you have your remotable object and a server object to listen for requests, create a client to consume it. The client is very simple. It will connect to the server, create an instance of the object from the server, and then execute the HelloWorld method.

Create a new C# console application project. Add a class called SampleRemotingClient and paste in the following code:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace CodeGuru.RemotingSample
{
   /// <remarks>
   /// Sample client to demonstrate the use of .NET remoting.
   /// </remarks>
   public class SampleRemotingClient
   {
      public static void Main()
      {
         // Create a channel for communicating w/ the remote object
         IpcClientChannel clientChannel = new IcpClientChannel();
         ChannelServices.RegisterChannel(clientChannel);

         // Create an instance of the remote object using the Activator
         SampleObject sample = (SampleObject) Activator.GetObject(
            typeof(CodeGuru.RemotingSample.SampleObject),
            "icp://hello/HelloWorld" );

         // Use the object
         if( sample.Equals(null) )
         {
            Console.WriteLine("Error: unable to locate server");
         }
         else
         {
            Console.WriteLine("{0}", sample.HelloWorld());
         }

         Console.WriteLine("Press the enter key to exit...");
         Console.ReadLine();
      }
   }
}

Add a reference to System.Runtime.Remoting in the project; otherwise, the IpcChannel and other related classes will not be found. In addition, add a reference to the project containing the SampleObject. Otherwise, the code will not compile because it won't know how to find a reference to SampleObject. Compile the class to make sure you have everything correct.

Alternately, the code for creating an instance of the remote object could also look like the code below:

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace CodeGuru.RemotingSample
{
   /// <remarks>
   /// Sample client to demonstrate the use of .NET remoting.
   /// </remarks>
   public class SampleRemotingClient
   {
      public static void Main()
      {
         // Create a channel for communicating w/ the remote object
         IpcClientChannel clientChannel = new IcpClientChannel();
         ChannelServices.RegisterChannel(clientChannel);

         // Register and create an instance of the remote object
         RemotingConfiguration.RegisterWellKnownClientType(
            Typeof(SampleObject),
            "ipc://hello/helloworld");
         SampleObject sample = new SampleObject();

         Console.WriteLine("{0}", sample.HelloWorld());
         Console.WriteLine("Press the enter key to exit...");
         Console.ReadLine();
      }
   }
}

Both accomplish the same thing, but the second version is a little cleaner in my opinion. It uses the RemotingConfiguration class to register the SampleObject to come from the remote location rather than using the Activator.

Putting It All Together to Test the IPC Remoting Sample

Once you have created the projects and successfully compiled each of them, you are ready to try it out. Start the server by running the compiled executable. After the server successfully starts, it will result in a console window being displayed with the message "Press the enter key to exit..." (see Figure 1).

[RemotingServer.jpg]

Figure 1. Remoting Server Console Window

The server is listening, so you are now ready to run the client. Executing the client, whether by running the executable or debugging in Visual Studio should result in "Hello World!" being displayed in a separate console window (see Figure 2). The window will pause until you press the Enter key to allow you time to see the resulting output message.

[RemotingClient.jpg]

Figure 2. Remoting Client Console Window

Straightforward Same-Box Communication

.NET remoting is a powerful way to enable interprocess communication. The addition of the IPC channel and System.Runtime.Remoting.Channels.Ipc namespace adds a well performing option for communicating across application domains located on the same computer. The code is similar to the TCP and HTTP channels, so it should be relatively straightforward to replace them with IPC for same-box communication.

Future Columns

The topic of the next column is yet to be determined. If you have something in particular that you would like to see explained here, you could reach me at mstrawmyer@crowechizek.com.



About the Author

Mark Strawmyer

Mark Strawmyer is a Senior Architect of .NET applications for large and mid-size organizations. He specializes in architecture, design and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C# for the fifth year in a row. You can reach Mark at mark.strawmyer@crowehorwath.com.

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • Live Event Date: December 18, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this upcoming webcast …

Most Popular Programming Stories

More for Developers

RSS Feeds