Getting Started with Remoting in .NET

Remoting is a means by which one operating system process, or program, can communicate with another process. The two processes can exist on the same computer or on two computers connected by a LAN or the Internet. Communicating between two programs may seem like a big “so what,” but it’s a rather involved process. Here’s why.

In any operating system, two paramount goals are security and stability. One way to achieve these goals is to load each executing program into its own process. By design, processes are isolated from each other?the code in one process cannot access the code or data of another process. That design enhances security by preventing one program from snooping around where it does not have access rights, and it enhances stability by ensuring that problems in one program cannot inadvertently corrupt the memory space of another program or of the operating system itself. The .NET Framework provides an additional level of isolation with application domains, which permit two or more programs to run within the same process, maintaining the same level of isolation as if they were in separate processes while minimizing the overhead of multiple processes.

Web services are probably the best known type of remoting, but they are not your only option.

While the need for isolation between processes is clear, the fact remains that separate programs sometimes do need to communicate. The emphasis on distributed computing and scalability makes this need even more prevalent today. The .NET Framework provides several method for cross-process communication, collectively called remoting. Web services are probably the best known type of remoting, but they are not your only option. In this article you’ll see an overview of .NET remoting technologies that may help you choose between the various remoting options..

Remoting makes an object in one process (the server) available to code in another process (the client). This is called marshalling, and there are two fundamentally different ways to marshal an object:

  • Marshal by value: the server creates a copy of the object passes the copy to the client.
  • Marshal by reference: the client creates a proxy for the object and then uses the proxy to access the object.

When a client makes a call to an object marshaled by value (MBV), the server creates an exact copy and sends that copy to the client. The client can then use the object’s data and executable functionality directly within its own process or application domain without making additional calls to the server. To implement MBV you must either implement the ISerializable interface in your classes, or mark them with the attribute.

In contrast, when a client makes a call to an object marshaled by reference (MBR), the .NET framework creates a proxy in the client’s application domain and the client uses that proxy to access the original object on the server. To implement MBR a class must, at minimum, extend the System.MarshalByRefObject class. Figure 1 illustrates the differences between MBV and MBR.

A channel is an object that implements communication between a client and a remote object, across app domain boundaries. The .NET Framework implements two default channel classes, as follows:

  • HttpChannel: Implements a channel that uses the HTTP protocol.
  • TcpChannel: Implements a channel that uses the TCP protocol (Transmission Control Protocol).

Both of these classes are dual-purpose in that they implement both a client channel, used on the client side to communicate with remote objects, and a server channel, used on the server side to communicate with clients. The HttpChannel class formats messages using the SOAP protocol, which encodes communications as XML. In contrast the TcpChannel class uses a binary format for messages. While binary formatting is more efficient (formatted messages are smaller), the plain text format of SOAP is much less likely to have problems with firewalls and other network security measures.

When you create a server?that is, a remotable class?you also define and register one or more channels for the class and associate each channel with a specific port. By registering a channel/port combination you tell the .NET infrastructure to listen on that port for messages intended for that channel. When a message arrives, the framework routes it to the correct server object. Figure 2 illustrates how the client and server communicate. Note that when you’re using remoting on a single system, the port numbers used by the client and server cannot be the same, because you can use a given port only once.

This demonstration program presents a simple remoting example. It illustrates the basic tasks involved in creating a remotable class, a server, and a client. To help keep things easy to understand, the demo makes use of .NET command line applications and the command-line compiler, but the same principles apply when you use remoting with other application types. To work with the demo, open a Visual Studio .NET (VS.NET) command prompt from the Start menu by selecting Microsoft Visual Studio .NET, then selecting Visual Studio .NET Tools, and finally Visual Studio .NET Command Prompt. The Command Prompt window opened by this command is like any other Windows command prompt but has the necessary environment and path variables set to let you use the VS.net command line compilers. Create a folder for the project, and make that folder current.

The remotable class (called RemoteClass) contains a single method that returns a “secret” word to the caller. The class constructor displays a console message when a client activates the class. I’ve included the console message for demonstration purposes only; it’s not required for the class to function. Listing 1 shows the source code for the RemoteClass. Note that the only aspect of the class related to remoting is that it inherits from MarshalByRefObject. You can create the demo code using any text editor and then save it in the project folder under the name RemoteClass.cs. Then, from the command prompt, compile the class using the following command (enter the command on a single line):

   csc /t:library /debug /r:System.Runtime.Remoting.dll       RemoteClass.cs 

The class compiles to the file RemoteClass.dll.

Next, you must build the client, which will call the remotable class. Listing 2 shows the client code, called Client.cs. The program does the following things:

  1. Creates a TcpChannel on port 8084.
  2. Registers the channel with the .NET infrastructure.
  3. Attempts to obtain a reference to the remote class by calling the Activator.GetObject() method.
  4. If the program can’t obtain a reference, it displays a message to the user. Otherwise it calls the remote object’s SecretWord() method and displays the returned data.

The call to the Activator.GetObject() method needs some more explanation. The method accepts two arguments. The first is the type of the remote class, which you can obtain by using the typeof() method with the class’s namespace and name as argument. The second argument has the following parts:

  • tcp://: identifies the protocol being used. Tcp is specified because the client and the server are using a TcpChannel for communication.
  • localhost: the name of the computer on which the remote class is located. In this sample, the remote class is on the same computer as the client, so the code uses the name “localhost”. If the class were located on a network computer with the name “BIGSERVER”, you would use that instead.
  • :8085: This identifies the port on which the remote class is listening.
  • /Secret: the URI associated with the remote class. This is an arbitrary name and can be anything you like as long as it matches the URI established by the server.

To compile the client, save the code as Client.cs and compile with the following command line (enter the command on a single line). Note that the compiler command specifies a reference to the remotable class RemoteClass.dll that you created previously.

Given the power of remoting, the relative ease with which you can accomplished it comes as a welcome surprise to many developers.
   csc /debug /r:remoteclass.dll       /r:System.Runtime.Remoting.dll Client.cs 

Finally, you need to create the server. The server listens for calls from clients and connects them to the remotable class. Listing 3 shows the server code. Here’s what the code does:

  1. Creates a new TcpChannel on port 8085. Note that this is the same channel on which the client will look for the remotable class.
  2. Registers the channel with the .NET infrastructure.
  3. Registers the remotable class using a call to the RemotingConfiguration.RegisterWellKnownServiceType() method. The arguments to this call are:
  4. The first argument identifies the class being registered.
  5. The second argument specifies the URI for the class. A client will use this URI when looking for the class.
  6. The third argument specifies that if there are multiple calls to the class (from more than one client), they will all be services by the same instance of the class.
  7. Display a message to the user and then pause until the user presses Enter.

Step 4 is required because the server must be executing to do its job. In other words, only while the server program is running will it “listen” for client requests for the remotable class.

To complete the server, save the code from Listing 3 as Server.cs and compile it with the following command line (enter the command on a single line):

   csc /debug /r:remoteclass.dll       /r:System.Runtime.Remoting.dll Server.cs 

Assuming all three parts of the project compiled successfully, you can test the program as follows.

  1. Open a second Command Prompt window and change to the project folder. You will now have two Command Prompt windows open (the need for this will become clear in a moment).
  2. In one of the windows enter “Server” to execute the server program. It will display the message “Hit to exit…”. The server is now waiting, listening for client requests for the remotable class.
  3. In the other Command prompt window enter “Client” to execute the client program. You’ll see two things happen:
  4. The client window displays the message “The secret word is REMOTING”, and the client program terminates.
  5. The server window displays the message “MyRemoteClass activated”, signaling that a client activated the remote class.
  6. To terminate the server, switch to the server window and press Enter.

You’ve seen a simple example introducing you to the .NET Framework’s remoting capabilities. Given the power of remoting, the relative ease with which you can accomplished it comes as a welcome surprise to many developers. While few real-world scenarios are as simple as the demonstration program presented here, the principles remain the same.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles:

©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.

Sitemap