Programming Examples

Are you a Programmer or Application Developer or a DBA? Take a cup of coffee, sit back and spend few minutes here :)

Client Activated Dotnet Remote Objects

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

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:

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

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

//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:

//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:

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

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

//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:

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

//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:

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

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

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.

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.

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:

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

  1. Right click the solution and Click rebuild all.
  2. Now navigate to both the EXE using windows explore.
  3. Run the Console Server.
  4. Run the Windows application.
  5. Click the button on the Windows application and Observe the result on the Client.

On Different Machines

  1. Copy Server EXE to a Machine say ROMAN-SERVER. Here, ROMAN-SERVER is the name of the server machine.
  2. Have the client on your machine itself. Before that Search for the keyword Localhost in the code and change it to ROMAN-SERVER.
  3. Run the console application in the Server Machine.
  4. Run the Windows client in your machine
  5. 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: , , ,

Do you like this Example? Share your thoughts!!

This site uses Akismet to reduce spam. Learn how your comment data is processed.