1. Introduction to Client Activated Remote Objects
In the past articles, we read about “Server Activated” remote objects. We also ran through separate article for Single Call and Singleton on the Server activated remote objects. In this post, we will try how to use the “Client activated” remote objects.
Before we go on Client Activated remote objects, we have to know what is activation and where the object lives. The clear fact whether it is server activated or client activated is that the remote object lives in the “Remote Pool” of the server. Client activation means, the client sets up the object on the server’s remote pool using the operator new in the client. So, if you are building up a class for the Client Activated Remote object, you have the power of using the overloaded constructors.
- In Server Activated, Single Call technique, the remote object is created during the remote call and destroyed when the call is over.
- In Server activated, Singleton style, server keeps a single object in the Pool for client requests between the remote call. All clients share the same object.
- In Client Activated system, the client sets up the object on the remote pool & the object is devoted to the client who made it. So here the object state can be unique for each object created by the clients.
2. About This Client Activated Remoting Example
First, have a look at the client & server’s screenshot below:

Client Activated Remote Objects – C# Dotnet Example
The console window is the server EXE that waits for the client’s activation request to host the object in the remote pool. The client is a windows application, which helps to study the client activated remote objects.
Set First Ac button creates a remote object on the remote pool. Display Ac1 retrieves the Objects state from the remote machine. Similarly, the other button pair does the same but talking with a different object. This will show how server keeps two unique objects in the remote pool. We will see how the ‘Display Ac1’ and ‘Display Ac2’ button clicks will fetch data from two different account object in the remote pool.
3. Account Class Server Object
We create the remote server as the C# console project. We name it as ServerCA. After creating the project dot net reference for
system.runtime.remoting
is added to it.
3.1 Namespace Inclusion
First, we provide the required namespace in the top. Below is the code:
1 2 |
//001 ServerCA : Name space for Client Activated Server using System.Runtime.Remoting; |
3.2 Account Class Private Members
We create account class which we will keep in remote pool. And, we derive this class from the
MarshalByRefObject
to support the remoting of the object created from it. Then we declare the variables related to our account class. These variable (in objects world, the object states) are useful to check how each client activated objects maintains their states.
1 2 3 4 5 6 |
//002 ServerCA : Remote Object, that will be Activated by Client public class Account : MarshalByRefObject { private int AcNumber; private string AcHolderName; private int AcBalance; |
3.3 Account Class Constructor
The constructor below initializes the data members of the Account class. We do not need more explanation in the code here.
1 2 3 4 5 6 7 8 |
//003 ServerCA : Initilize the Ac with zero, noname public Account() { AcNumber = 0; AcHolderName = ""; AcBalance = 0; Console.WriteLine("Account Object Created - Default Ctor"); } |
3.4 Overloaded Constructor for Client Activated Remote Class
We add one more constructor for our Account class that helps to initialize the data members dynamically. Note that the Server Activated remote class does not support these kinds of overloaded constructors. Refer the past articles on Dot Net Remoting to know about the server activated remote objects. As the client activates the object of this class using the operator new, it is now viable to have the overloaded constructors. This means, our class can have constructors that accepts parameters to it. Below is the code for it:
1 2 3 4 5 6 7 8 9 |
//004 ServerCA : Accout with Data. Note Constructor is Overloaded as the activation // type we are going to set is Client public Account(int AcNo, string Name, int Bal) { AcNumber = AcNo; AcHolderName = Name; AcBalance = Bal; Console.WriteLine("Account Object Created - Overloaded Ctor"); } |
3.5 Get and Set Methods Of Account Class
OK. Now the account class has data members and constructors to initialize the data members. When the client constructs the remote object using its default constructor, we should have a way to initialize its members. So we will provide a get and set methods for the members. Below is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//005 ServerCA : Set methods for the Private data members public void SetAcNumber(int AcNo) { AcNumber = AcNo; } public void SetAcName(string Name) { AcHolderName = Name; } public void SetBalance(int Bal) { AcBalance = Bal; } //006 ServerCA : Get methods for the Private data members public int GetAcNumber() { Console.WriteLine("Account Number Requested"); return AcNumber; } public string GetAcName() { Console.WriteLine("Account Name Requested"); return AcHolderName; } public int GetBalance() { Console.WriteLine("Account Balanced retrieved"); return AcBalance; } |
4. Registering Account as Remote Object
The account class is ready. In this section, we will register it as a remote object. Before we proceed, first we will add the required namespaces.
1 2 3 4 |
//007 ServerCA: Required Namespaces using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; |
4.1 Communication Channel
The program entry function Registers the required communication channel. Here the sample code takes the HTTP communication channel and registers the port 10038 for communication.
1 2 3 |
//008 ServerCS : Setup the Http Channel and Register it HttpChannel port = new HttpChannel(10038); ChannelServices.RegisterChannel(port, false); |
4.2 Specify Account as Client Activated Through RemotingConfiguration
RemotingConfiguration
class of Dotnet gives various static members to configure the remoting framework. In the below code, we set Application Name as ‘
ServerCA
’ through
RemotingConfiguration
. The client uses this name when making a service call to the server.
RegisterActivatedServiceType
is a static function in the
RemotingConfiguration
. We call this method to tell the server that client machine will activate the Account class. Now our server will keep the
Account
class in the remote pool when the client creates it using the new keyword. Below code registers the Account object as a client activated remote object:
1 2 3 4 |
//009 ServerCS : Set the App Name and Register the object type that // need to be activated by the client. RemotingConfiguration.ApplicationName = "ServerCA"; RemotingConfiguration.RegisterActivatedServiceType(typeof(SercerCA.Account)); |
4.3 Keep the Server Running
After writing the information message on the console window, the server keeps running. The message says that user can hit any key to kill the server.
1 2 3 |
//010 ServerCS : Inform Server is ready Console.WriteLine("Server is ready to Demo Client Activated Objects..."); Console.ReadLine(); |
5. Recap of Work Done So For
The server is ready now. First, we created the Account class as a remote class by deriving it from the
MarshalByRefObject
. We provided some data members to it. Then to access these members, we added the get and set member functions to it. Also, we defined two constructors as it will activated by a client machine. Then in the main program entry, we registered an HTTP communication channel claiming a port 10038 for dedicated use. Now, let us move to the client and see how it activates the
Account
object from this running server.
6. Client Project Activating Account on Server
The client is a windows application. We name the project as
ClientCA
. To know the form setup, download the code and check the properties for each control that appears in bold. What the client will do is already explained in section 2 of this article.
6.1 Project Reference Setup
As a first step, we add the project to the same server project using File->Add->New project. The reference to
System.Runtime.remoting
is done through the .Net tab of the reference dialog. Also, for this client windows project, we add the sever project as a reference using the same Add Reference Dialog’s projects tab.
6.2 Remoting Namespace
In the form main class, we include the following name spaces including remote server project:
1 2 3 4 5 6 |
//ClientCA 001: Set the Required Namespaces. using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime.Remoting.Activation; using SercerCA; |
6.3 Client & Server Executable
Two instances of Account class are declared in the Form class. Note that we already provided the Server project as a reference. When the solution (Visual Studio created it for us when we added the second project) is built, it will give two exes. One for Client (Windows App) and another one is for Server (Console App). We may take these EXEs and deploy it on the server and client machines for testing.
1 2 3 |
//ClientCA 002 : Declare the Objects that need to be created on server //and activation is done by the client Account account1, account2; |
6.4 Claiming Account as Client-Activated From Caller Side
In the constructor for the form handed over by the IDE, the client registers the Account class of the Remote server. Note that the server already said that the Account class is a Client-Activated object by using the utility function
RegisterActivatedService
type. The below client code tells the Remoting Run-time that it can activate the Account class any time using the utility function
RegisterActivatedClientType
. Once server and client are agreed upon the activation of the Account object, the client can instantiate the Account object just like how it sets up the other normal class objects.
1 2 3 4 5 6 7 8 9 |
public frmAcManager() { InitializeComponent(); //ClientCA 003 : Register the Client Activated type from the remote Pool. //Note, Server already registered Account as the Activated Type. RemotingConfiguration.RegisterActivatedClientType(typeof(Account), "http://localhost:10038/ServerCA"); } |
7. Activating Remote Objects From Client
In this section, we will activate two remote objects from the client machine. The client maintains the state of these remote objects separately which we will understand while coding.
7.1 Activate First Remote Object Using Default Constructor
The client sets up the
Account
object using the new keyword. Here, the client uses the default constructor and then sets the variables through the set functions. Note, our windows client activates the
Account
object in the server and server keeps it in the Remote Pool. So now there is an
Account
object in the server’s remote pool which is activated by the client. Read our past articles to know how the client seeks Server Activated remote object.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
private void btnAc1Set_Click(object sender, EventArgs e) { //ClientCA 004 : Create the Account Object1 account1 = new Account(); account1.SetAcNumber( Int32.Parse(txtAcNo.Text)); account1.SetAcName(txtAcName.Text); account1.SetBalance(Int32.Parse(txtBalance.Text)); //Clear the Fields and Say Account created txtAcName.Text = ""; txtAcNo.Text = ""; txtBalance.Text = ""; MessageBox.Show("Account Created"); } |
7.2 Activate Second Remote Object Using Overloaded Constructor
The client creates the second Account via the overloaded constructor. This object also now sits in the remote pool of the server. There are two objects in the server and the client activated their life. Also, note that these two objects maintain their object state independently. For Example, Account1 may have a balance of 1000 and Account2 may have a different balance of 1200. To see that, we handle click events of the remaining two buttons.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private void btnAc2Set_Click(object sender, EventArgs e) { //ClientCA 005 : Create the Account object2 using overloaded Constructor int AcNo = Int32.Parse(txtAcNo.Text); int Bal = Int32.Parse(txtBalance.Text ); account2 = new Account(AcNo, txtAcName.Text, Bal); //Clear the Fields and Say Account created txtAcName.Text = ""; txtAcNo.Text = ""; txtBalance.Text = ""; MessageBox.Show("Account Created"); } |
8. Get Data From the Remote Objects
The next two button events uses the remote objects in the server to get the account information. You can notice how server contacts the correct object in the remote pools and fulfills the service call. Below is the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
private void btnAc1Get_Click(object sender, EventArgs e) { //ClientCA 006 : Get the Details of First Object. txtAcName.Text = account1.GetAcName(); txtAcNo.Text = account1.GetAcNumber().ToString(); txtBalance.Text = account1.GetBalance().ToString(); } private void btnAc2Get_Click(object sender, EventArgs e) { //ClientCA 007 : Get the Details of First Object. txtAcName.Text = account2.GetAcName(); txtAcNo.Text = account2.GetAcNumber().ToString(); txtBalance.Text = account2.GetBalance().ToString(); } |
9. Testing the Example
On Same Machine
- Right click the solution and Click rebuild all.
- Now navigate to both the EXE using windows explore.
- Run the Console Server.
- Run the Windows application.
- Click the button on the Windows application and Observe the result on the Client.
On Different Machines
- Copy Server EXE to a Machine say ROMAN-SERVER. Here, ROMAN-SERVER is the name of the server machine.
- Have the client on your machine itself. Before that Search for the keyword Localhost in the code and change it to ROMAN-SERVER.
- Run the console application in the Server Machine.
- Run the Windows client in your machine
- Now you can test the client.
You may have a Question that when will the client-activated objects removed from the remote pool. How does the GC work? OK. You should search for object Lease Time in google to further exploration.
Source Code and Running App Demo: Download From Google Drive
- Note: The samples are created using the VS2005 IDE
- Extracted Zip gives you Source Code and Video of Testing the App. To see the video, set the resolution to 800 x 600 and use full-screen option from the video.
Categories: Remoting
Tags: # RegisterActivatedClientType, C# MarshalByRefObject, C# RegisterActivatedServiceType, C# RemotingConfiguration