1. Introduction
.NET remoting is client and server based distributed object technology. In this first article about .NET remoting, we will create a remote server and client application. We will go ahead and start creating the application and I will give the explanation when we are developing the example.
2. About this Example
The server we are going to create is a console application. This console application will host our remote objects on the server and the client will make a call to the public
members (usually function).
The client is a Windows Form application, which will get access to the remotely hosted objects and start using it. Below is the screen shot of the client application.
When we click the Get Details button, the client makes a call to the remote server console application to get the customer id and customer name from the remote objects. Last deposit and Last withdraw is populated by getting the LastTrans
object from the remote object. I will explain other concepts when we move along.
First, we will go ahead and start our Remote server console application.
3. Remote Server Console App
- Create a new console application and name it
ConServer
.
- Right click the
ConServer
project and choose Add reference.
- From the dialog displayed, select
System.Runtime.Remoting
from the .NET tab and click the OK button. This step provides access to the .NET remoting API.
- Next add a class named
LastTrans
to the project. Add one more class and name it as RemCustomer
.
Explanation
We have created a console application project and then got access to the .NET remoting assemblies. Then we added to classes to the project. RemoteObject
is the one which will be kept in the Server’s memory. And LastTrans
object is created in the server but it will be sent to client through serialization using the RemoteObject
.
Serialization is a technique, which converts your class in the form of bit streams and these steams in the receiving end is collected to form the object. In our example, we sent the LastTrans
through serialization to the client.
All the skeleton of our server is kept ready by the IDE. Now we will go ahead and add code.
4. The LastTrans Class
- Locate the
LastTrans
class created by the IDE and mark it as Serializable
by adding the serializable
attribute before the class. Below is the code for it:
[Serializable()]
public class LastTrans
- Add
private
variable to this class:
private int LastDeposit;
private int LastWithdraw;
- In the constructor, initialize the above declared
private
variables. Note that here I hard-coded the values. In the real world, it will be queried from the database to get the latest result. Below is the code:
public LastTrans()
{
LastDeposit = 68800;
LastWithdraw = 12000;
}
- Next, provide a function to return the
private
variables. The client to get the Last Deposit as well as Last Withdrawal amount uses these functions.
public int GetLastDeposit()
{
Console.WriteLine("Last deposit Queried...");
return LastDeposit;
}
public int GetLastWithdraw()
{
Console.WriteLine("Last Withdrawal amount Queried...");
return LastWithdraw;
}
Note that the console write line does not print anything on our Remote Server because, the object is serialized and sent to client. The client creates this object and subsequent call on the object gets executed in the client machine.
5. The RemCustomer Class
- Include the below specified
namespace
:
using System.Runtime;
- This class acts as the remote object. To make the IDE created object (Refer to step 4), locate the class and derive it from the
MarshalByrefObject
. OK. Why is that derivation required. It is required as we are planning to keep this object server’s remote pool. Below is the second step of the code:
public class RemCustomer : System.MarshalByRefObject
- Next, declare the members for this class. Note that our remote object is going to serve the client both standard data type as well as user defined type. User defined type here is
LastTrans
which you already saw that we marked it as serializable
.
private string CustName;
private int CustId;
private LastTrans trans;
- The constructor will initialize the members declared. Constructor is below:
public RemCustomer()
{
CustName = "Ram Gopal";
CustId = 1235;
Console.WriteLine("Instance of Remote object Created...");
trans = new LastTrans();
Console.WriteLine("Instance of Last Transaction object created. ");
}
- Other member functions are shown below. These can be easily understandable.
public int Get_id()
{
Console.WriteLine("Customer Id requested...");
return CustId;
}
public string Get_Name()
{
Console.WriteLine("Customer Name requested...");
return CustName;
}
public LastTrans GetLastTrans()
{
Console.WriteLine("Transaction object requested...");
return trans;
}
Now our remote class is also ready to serve the Windows Form client. Note that the MarshalByrefObject
states that this RemCustomer
will reside on the server and a reference to it is sent to the client. The client calls that reference as proxy. We will move to our last step which is the program entry point of console application.
6. Hosting the Remote Object on the Server
- Locate the
static void main
, which is the program entry point for the console application. In the top of the file (Program.cs if you had not changed the file name), include the assemblies. Below is the code:
using System.Runtime;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
- Next a TCP channel with port number 13340 is created and registered in the server machine. Client will use this port to communicate with remote object. The below code creates a TCP communication channel and registers it with the server machine in which the server application is going to run.
TcpServerChannel SrvrChnl = new TcpServerChannel(13340);
ChannelServices.RegisterChannel(SrvrChnl, false);
- Once the communication method is specified, it is time to register our remote object in the server machine. The first parameter to the function specifies the type of the object that is registered. The second one gives a unique name for the registered object. I have kept the registration name the same as the class name. But, you can use a different name. Client should use the same name when they ask for the Proxy of the remote object. The third parameter says how the serve should activate the remote object. In this example, we are using the Single Call method. That means, for each client call, an object will be created and maintained in the pool.
We will look at a singleton method in the next article:
RemotingConfiguration.RegisterWellKnownServiceType
(typeof(ConServer.RemCustomer), "RemCustomer",
WellKnownObjectMode.SingleCall);
- The server is ready. Break the execution using the
ReadKey
method.
Console.WriteLine("Server is Running...");
Console.WriteLine("Press Any key to halt the Server");
Console.ReadKey();
If you want, you can run the server now. But, there is nobody to consume the registered remote object on you server. We will now move to creating the Client. Below is a screen shot:
Note: The remote object is not created as the activation method SingleCall
. For each client, call a separate instance of the remCustomer
will be created and kept in the remote object pool.
7. Prepare the Client Application
As you already know, client is a Windows Form application. Follow the steps below to create the client application that uses the remote object hosted by our console server.
- Make sure the Console server project is still in open state.
- Click on File|Add|New Project.
- Select Visual C# in the project Types and Select Windows Application from the available template.
- Name the project as
RemClient
and click ok.
- Design your form by referring the first screen shot. Download the attached project for your reference and set the properties by referring it. ConServer.sln will open both the projects. In your case, this solution will be created now as you are adding one more project. A solution file is the combination of two or more projects.
- Add a reference for Remoting assembly as you did in the server step 3.
- Once your form is designed, double click the Button control to get the Click event handler for it.
- Right click the
RemClient
project and select add reference. Go to the project tab and select ConServer
project.
Explanation
In the above steps, you created a Windows application and designed the form. You added reference to the .NET's Remoting
assembly and added a reference to the ConServer
application. If we use the interfaces, we can avoid this project reference. We will see that in a separate article.
8. Start Coding the Client
- First include the below specified namespaces on top of the file which has the click event handler for the button. The code is below:
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using ConServer;
- Now we will implement the click event handler. The button click will invoke the
public
functions exposed by the Remote
object. Make sure the RemCustomer
on your server application is Public
. The first step is to get the Proxy for the remote object hosted by the Console Application, which runs on Local or Remote machine. Below is the code for doing that:
RemCustomer remoteCust = (RemCustomer)Activator.GetObject(typeof(RemCustomer),
"tcp://localhost:13340/RemCustomer");
In the first parameter, we specified what object we are looking for. In our case, it is the actual object type. The project reference we added is just to resolve this type (RemCustomer
) name. But, in the interface approach, it is not required to reference the server project. Just an interface type is required on both server and client. If the client develops the application to invoke the third party remote object, then the server developers usually provide the interface. By doing that server piece of implementation is not revealed to the client developers. In our case, let us assume that the same party develops server and the client.
The second string
parameter has three parts in it. The first one is machine name. As tested the applications (Server, Client) on the same machine I kept localhost. If the Server application is running on the machine names C-AshCorner_01 then the localhost in the string
should be replaced by the machine name; that is; C-AshCorner_01. Note you can also use the IP address of that machine.
Well. The client now knows which machine it need make connection to get the RemCustomer
proxy. But the server may have a lot of network communication right? It may be an Oracle server or Sql2005 server or even a Jboss web server. How does the server make communication? That is why we registered the server with a port number 13340. This port on TCP communication is called dedicated port. Oracle has its dedicated port. Jboss has it own dedicated port. Our application server registered the port 13340 saying “This port is in use like 80 for http”. Our client application by specifying this port number next to the machine name, sets-up the communication for connection request. The last part specifies the registered name of remote object. Look at the Section 6 point 3.
Finally, we performed a type cast and stored the proxy in the remoteCust
.
In summary, to get the remote object:
- First a machine name is resolved
- A port number specifying which particular Server Application contacted.
- The registered name specifies a single object type upon several registered remote objects (We registered only one)
- Once the proxy is with us, make a call to the functions through proxy. Note proxy just shows that the object is with you, but it is not. All the calls are transmitted to the server to get the result. Below is the code, which makes use of the proxy object to make a call on the
public
functions, exposed by the remote object remCutomer
.
int id = remoteCust.Get_id();
string name = remoteCust.Get_Name();
LastTrans trans = remoteCust.GetLastTrans();
int lastdeposit = trans.GetLastDeposit();
int lastwithdraw = trans.GetLastWithdraw();
txtCustId.Text = id.ToString();
txtCustName.Text = name;
txtLastDeposit.Text = lastdeposit.ToString();
txtLastWithdraw.Text = lastwithdraw.ToString();
btnInvokeRemote.Enabled = false;
The picture below explains how the application will work:
9. Testing the Application
On the Same Machine
- Right click the solution and Click rebuild all.
- Now navigate to both the EXEs using Windows Explorer.
- 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 to a Machine, say Mahesh. Here, mahesh is the name of the machine.
- Have the client on your machine itself. Before that, search for the keyword
Localhost
and change it to Mahesh.
- Run the server at machine mahesh.
- Run the client at your machine.
- Click the Get Details button.
Note: You can use IP address also in-place of Machine Name.
10. Closing Note
- To see the result live, download the screen cam: Download
- To know how to debug, download to see the steps: Download