.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.
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.