.NET Remoting - by Alain "Lino" Tadros

By: Lino Tadros

Abstract: This article will explain and demonstrate the .NET Remoting framework and build Remotable Objects, Hosting servers and Clients to exercise the different activation models.

.NET Remoting - by Lino Tadros

If you have ever worked with DCOM or CORBA, then you have an understanding of how to work with Remote Objects and how to deal with application communications across boundaries.   .NET Remoting is Microsofts new infrastructure that provides a rich set of classes that allow developers to ignore most of the complexities of deploying and managing remote objects. In .NET Remoting, calling methods on remote objects is nearly identical to calling local methods.   My goal in this article is to introduce you to the principles of architecting and developing .NET Remoting solutions while utilizing the Delphi for .NET preview to start getting you used to it.

Simple idea:

 When a client creates an instance of a remote object, it receives a proxy to the class instance on the server. All methods called on the proxy will automatically be forwarded to the remote class and any results will be returned to the client. From the client's perspective, this process is no different than making a local call.


The rules of engagement:

First, any Remoting Object has to inherit from MarshallByRefObject because all Remoting Objects are returned by Reference.

On the other hand, Objects passed as parameters to a remote method call or a return type of a remote method call can be forwarded by value or by reference, as we are going to see soon.

 

Second, lets understand the activation model.  There are 2 activation models for Remote Objects:

  • Server Side Activation (You can also call this method Well Known activation):
  • Client Side Activation.

 

The Server Side Activation is when the Remote object is created and executed totally on the server side while the client creates a proxy to trick it into thinking that the Object is available on the client side.  Even in this activation model we have 2 separate ways to deal with the state fullness of the Object:

 

SingleCall: The SingleCall flag notifies the server that each remote method call into the server will create a new instance of the object on the server which means there will be no state kept for that object on the server between method calls.

 

Singleton: The Singleton flag notifies the server that remote method calls into the server do not destroy the instance of the remote object on the server after the method returns which means subsequent calls from the client can take advantage of the state of the object made from previous calls.

 

 

The second activation model is the Client Side Activation, and that is when the client is allowed to pass parameters to the constructor of a remote object when it gets created.  The trick here is that the Object in question has to have the [Serializable] attribute set.

 

We talked about the Remote Object semantics, now lets talk about the means in how the .NET Remoting framework accomplishs its task.

3 main and distinct ideas allow the .NET Remoting richness for remote communication:

  • Channels
  • Formatters
  • Sink Objects

 

Channels:

Are the protocols on which the whole remote communications will take place.  .NET Remoting framework has 2 built in channels for immediate use, TCP/IP and HTTP.  Developers have the opportunity to extend the framework and implement their own Channel which plugs in to the rest of the .NET Remoting infrastructure.

 

Formatters:

Are the formats in which the Objects travel back and forth between clients and servers.  For the 2 built in Channels for instance, SOAP(XML) is the format used for HTTP channel and Binary is the format used for TCP/IP.  Again you can implement your own Formatters and plug them into the current infrastructure.

 

Finally, the Sink Objects:

Another proof of the flexibility of the Frameworks is that it allows objects (called Sink Objects) to be pluggable to enhance, customize and incorporate security for Remote Objects on the wire. For example, you could create your own Sink Object that would allow you to encode a Remote Object, or you could implement a custom security mechanism

Ok, let's write some code :)

We are going to create a solution based on 3 separate projects, a library for the
Business Object, then a Server to utilize the Business Object and sets its Channel
and characteristics and finally a client that exercises the whole Remoting concept.

You can download the code from: http://codecentral.borland.com/codecentral/ccWeb.exe/listing?id=19484

First we write the Business Object:


library DRemBO;

uses
  System.Runtime.Remoting;

type
  TFalafelObject = class(MarshalByRefObject)
  private
   PrevName: string;
   NumPeople: integer;
  public
    constructor create;
    function GetMessage(name: string): string;
  end;

{ TFalafelObject }

constructor TFalafelObject.create;
begin
  inherited;
  Console.WriteLine('Object Created');
  PrevName:= '';
  NumPeople:= 1;
end;

function TFalafelObject.GetMessage(name: string): string;
var
  msg: string;
begin
  Console.WriteLine('GetMessage has been called');
  if PrevName='' then
    msg:= 'Hi ' + name + ' you are the first to call into this Object!'
  else
    msg:= 'Hi ' + name + ' you are the person number ' + IntToStr(numpeople) +
      ' to call into this Object';

  PrevName := name;
  inc(numpeople);
  result:= msg;
end;

begin

end.

Build the Library from the command line:   dccil DRemBO.dpr

Please notice that the Class derived from MarshalByRefObject which is a must to allow
the Object to be remotable.

Next we will create a server:


program DRemHost;

uses
  System.Windows.Forms,
  System.Runtime.Remoting,
  System.Runtime.Remoting.Channels,
  System.Runtime.Remoting.Channels.Tcp,
  DRemBO;

var
  tcp: TcpChannel;
  HostedObject: TFalafelObject;

begin
  Console.WriteLine('Host Started');
  Tcp:= TcpChannel.Create(7777);
  ChannelServices.RegisterChannel(tcp);

  HostedObject:= TFalafelObject.Create;
  Remotingservices.Marshal(HostedObject, 'BO');
  Console.Readline();
end.

The trick here is how to build this server while referencing the Business Object assembly we just created. Easy! We use the following command line
dccil -LUDRemBO -CC DRemHost.dpr

-LU will cause the compiler to create DCUIL file for the Assembly because we are using the namespace in the uses clause of the server.
-CC will force the creation of a Console Application.
Voila!

There are some interesting lines of code here, first we chose to utilize
the TCP/IP channel and we used the TCPChannel class to create an instance
on the 7777 port then we registered the Channel. Get used to that, this
is how it is always going to work. The Marshal call is to define HOW
it is going to work, this is a very simple way of saying, as soon as the
object is created on the client, create it on the server as well.
Later we will use some other mechanism to NOT create the object on the
server until a method is called from the client.

Finally we create the Client:


program DRemClient;

uses
  System.Windows.Forms,
  System.Runtime.Remoting,
  System.Runtime.Remoting.Channels,
  System.Runtime.Remoting.Channels.Tcp,
  DRemBO;

var
  MyBO: TFalafelObject;
  str: string;
begin
  MyBO:= TFalafelObject(RemotingServices.Connect(typeof(TFalafelObject), 'tcp://localhost:7777/BO'));
  Console.WriteLine('Please enter you name ');
  str:= MyBO.GetMessage(Console.ReadLine());
  Console.WriteLine(str);
  Console.Readline();
end.

Use the following command line: dccil -LUDRemBO -CC DRemClient.dpr

There is only ONE interesting line of code here, how do we connect to our Remote Object.  Here you will see the client creating a proxy that will allow it to make calls against the Remote Object as if it was available in the client Application.

Run the Host (Server) from the command line.  You will notice that the OBJECT starts immediately without even having a Client available.

Run the Client and enter your name, you will notice the Call being made into the server.  If you start another instance of the client and enter a new name, make note that the server kept state of the Object on the server because the server never destroyed the instance of the Object.

Well that was the easiest way to create the Object, by allowing the server to create it at startup and manage it indefinitely.

Now let's change the Server a little to exercise the 2 different Server Side Activation methods.


program DRemHost;

uses
  System.Windows.Forms,
  System.Runtime.Remoting,
  System.Runtime.Remoting.Channels,
  System.Runtime.Remoting.Channels.Tcp,
  DRemBO;

var
  tcp: TcpChannel;
  HostedObject: TFalafelObject;

begin
 
  Console.WriteLine('Host Started');
  Tcp:= TcpChannel.Create(7777);
  ChannelServices.RegisterChannel(tcp);

  RemotingConfiguration.ApplicationName:= 'Lino';
  RemotingConfiguration.RegisterWellKnownServiceType(typeof(TFalafelObject), 'BO', WellKnownObjectMode.SingleCall);

  Console.Readline();
end.

We are going to give the Application a name say "Lino" and now the call is going to be a registration to Server Side Activation type based on SingleCall or Singleton.

Remember WELL KNOWN = Server Side Activation.

We gave it a name just in case we need to get the tcp:// URL by name: tcp://localhost:7777/Lino/BO instead of tcp://localhost:777/BO
Compile and run the host again, notice that the server does not create the OBJECT automatically, only when the Client calls the GetMessage method is when the Server is going to create the Object.
Finally the difference between using the SingleCall and Singleton enums, will manifest itself when you start several clients to hit the server.  The SingleCall will always show that you are the first to hit the object because you get a new object every time a call is made.  The Singleton enum will cause the server to keep track of state because it will not destroy the object and will reuse for subsequent calls.

In a future article I will explain how to do Client Side activation based on Serialized Objects.

I can not show you the Client Side Activation right now because of a bug in the compiler preview that does not allow us to create parameterized constructors correctly.

Thank you for your time and write to you later.

About Falafel Software Inc:

Falafel Software is all about making the most of software development technology in order to complete the project on time and on budget with best possible user experience. Falafel Software offers a comprehensive suite of software development solutions ranging from strategy to design to implementation that businesses need in order to realize high returns on their investment.

 Falafel Logo

Copyright ) 2003 Alain Tadros, Falafel Software Inc.
ALL RIGHTS RESERVED. NO PART OF THIS DOCUMENT CAN BE COPIED IN ANY FORM WITHOUT THE EXPRESS, WRITTEN CONSENT OF THE AUTHOR.



Server Response from: ETNASC03