|
An introduction to .Net Remoting part 2 of 4.
|
| Object Activation |
|
Object activation refers to the various ways in which a remote object can be instantiated.
We begin with a detailed examination of the possible types of object activation and their
ramifications. Marshal By Value objects have a simple activation scheme, they are crerated
when the client first requests them. Marshal By Reference objects have two activation schemes:
|
|
Server Activated Objects (SAO)
|
|
Client Activated Objects (CAO)
|
|
Server Activated Objects. (Well-Known) Before a remote method can be invoked on
a remote object, the remote object must exist or be created. Server Activated Objects are
created only when the client makes the first call to the remote method.
In other words, when the client asked for the creation of the remote object only the local
proxy is created onthe client, the actual remote object on the server is instantiated on the
first method call.So, how do we generate one? Here is an example:
|
...
// On the Server
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteServerObject), "Test",
WellKnownObjectMode.SingleCall);
...
// On the Client
IRemoteCom obj = (IRemoteCom)Activator.GetObject(typeof(IRemoteCom), "tcp://localhost:1002/Test");
...
|
|
SAO have two registration types, Singleton and SingleCall.
|
Singleton objects, as the name implies, are instantiated one time only, and services all
client requests in a multi-threaded fashion. SingleCall object are at the other extreme,
everytime a remote method is invoked on these types of SAO a new remote object is created.
The new instance services the request and is then left for the garbage collector to dispose.
These can be acomplished on the server as follows::
|
RemotingConfiguration.RegisterWellKnownServiceType( typeof(RemoteServerObject), "Test",
WellKnownObjectMode.SingleCall);
...
RemotingConfiguration.RegisterWellKnownServiceType( typeof(RemoteServerObject), "Test",
WellKnownObjectMode.Singleton);
|
For SAOs the proxy object (on the client) and the actual object (on the server) are created
at different times, for this reason only default constructors can be used for SAOs. If an
SAO object requires a non-default constructor you can use the factory pattern for provide one.
Note that if a Singleton object has been removed by the garbage collector, a new one will be
created on a subsequent client call.
|
|
Client Activated Objects. (Activated) These are created on the server immediately
upon the client's request. An instance of a CAO is cretated every time the client instiantiates
one, either by the use of new or Activator.CreateInstance(...)
|
...
// On the Server
RemotingConfiguration.ApplicationName = "TestCAO";
RemotingConfiguration.RegisterActivatedServiceType(typeof(RemoteObjectCAO));
...
// On the Client
RemotingConfiguration.RegisterActivatedClientType(typeof(RemoteObjectCAO),
"tcp://localhost:1002/TestCAO");
obj = new RemoteObjectCAO();
...
|
In all these examples "localhost" can be replaced with an actual remote machine's IP address.
The following shows a small example of a few of these ideas.
|
|
On startup the server registers all of its remote object types and waits. The client consistes
of three examples, a Singleton SAO, a SingleCall SAO and a CAO. The SAO examples demostrates the
key fact about SAOs, object creation is done at the time of the first method's invocation, also
the Singleton object is instiantiated once while the SingleCall objects are instiantiated each time
a call is made. The CAO object is created right away. When an object is passed to a remote method
as ref it behaves exactly as expected any changes to the reference parameter is marshaled back
to the caller (client). A word of caution, in order to keep the examples as simple and as clear as
possible the CAO button on the client constructs a class that calls
RemotingConfiguration.RegisterActivatedClientType(...) this should only be done once, not
each time a class is instiantiated. For this reason I have disabled the button after the first click.
|
| Object Lifetime And Configurtion |
We have seen three main categories of MBR server-side objects, two SAO types and the CAO type.
An SAO that has been registered as SingelCall has a very simple and limited lifetime.
It lives for a single call only, thereafter it is marked for removal by the Garbage Collector.
The other two types Singleton and CAO have their lifetimes managed by a service
introduced by the .Net Framework, the Leased Based Manager, on the server the application
domain's lease manager determines when a server-side object should be marked for deletion. Each
application domain has its own lease manager object. A sponsor is any object that the
lease manager can call to determine wether or not a remote object's lifetime lease should be
extended. Notice that under this scheme the remote object's (server-side object) lifetime is
independent of the client object's lifetime. The decoupling of the server and client lifetimes
is a very flexable design. Consider the following, a remote object that is costly to instiantiate
can be given a long lifetime lease or can be kept alive by a sponsor. In addition a remote object
that holds scarce or important resources can be given short lifetimes and be reclaimed by the
Garbage Collector quickly. More importantly, this decoupling gurantees that the remoteobject
will have a finite lifetime regardless of network conditions or the existance of any clients.
The default settings for the lease mamager are five minutes for initial time-to-live, poll every
ten seconds, and add an additional two minutes for every remote call by a client. All these
values are configurable, we can override MarshalByRefObject InitializeLifetimeService() to
define our own values.
|
|
So far we have configured all of our remote objects programatically, both on the server and the client.
There is another mechanism for doing this that does not require a recompile, an xml configuration file.
By convention, the configuration file name has the format executablename.config. In the
application we have to call RemotingConfiguration.Configure(filename) in place of what we have
been doing. Here is an example the filename is server.exe.config:
|
<configuration>
<system.runtime.remoting>
<application>
<channels>
<channel ref="tcp" port=1002 />
</channels>
<service>
<wellknown mode="Singleton" type="TestSAOSingleton" />
<activated mode="SingleCall" type="TestSAOSingleCall" />
</service>
<lifetime leaseTime="10M" sponsorshipTimeOut="2M"
renewOnCallTime = "2M"
LeaseManagePollTime="10s"/>
</application>
</system.runtime.remoting>
</configuration>
|