Wednesday, September 5, 2007

Remoting in C#

While you are developing distributed application by csharp, you might need to have communication between objects that run in different processes.
.NET remoting enables client applications to use objects in other processes on the same computer or on any other computer available on its network.(MSDN)

Each remoting application consist of three part:

  • A remotable object.

  • A host application domain to listen for requests for that object.

  • A client application domain that makes requests for that object.

We have two kind of remotable objects, one Marshal-by-value objects and Marshal-by-reference objects.
  • Marshal-by-value objects are either inherited from ISerializable interface or using a Serializable attribute, which are copied and passed from the application domain.
  • Marshal-by-reference objects are the objects from a class which is inherited from MarshalByRefObject class.
Notice that the objects from other classes which are not in that two types cannot be used in remoting.

Part 1: Remotable Types
In my first post about remoting I will create a class named "MyRemotableType" which is a Marshal-by-reference type, and I will put this class into a class library with name MyRemotableTypes.dll.

public class MyRemotableType:MarshalByRefObject
{
public MyRemotableType()
{
Console.WriteLine("A New MarshalByRefObject created");
}
public void AddNumbers(int a,int b)
{
Console.WriteLine("Sum is : {0}",a+b);
}

public string CaldSum(int a,int b)
{
return string.Format("Sum is: {0}", a + b);
}

}


Notice that Marshal-by-reference objects needs to be activated. Activation for Marshal-by-reference objects has two types:
  • Server activation: which means that objects will be created by server at the first method call, but not when the object is initializing by calling new keyword.
  • Client activation: which means that objects will be created by server when the client calls the new keyword.
Server activation it self contains two types, which can be specified with using WellKnownObjectMode enumeration items:
  • Singleton: It means that there will always be only one instance, regardless of how many clients there are for that object, and which have a default lifetime.
  • SingleCall: It means that the system creates a new object for each client method invocation.
Part 2: Host Application
Now I need another application which will listen to request from clients. In this sample I 'm going to create a console application. First I have to add a reference to System.RunTime.Remoting. Then I have to prepare a communication line between clients and server. To do this you can use a TCP or HTTP channel. Like this:

HttpChannel channel = new HttpChannel(1234);
ChannelServices.RegisterChannel(channel);

Then you have register the remotable types you want to prepare. As I said before you can choose with activation you want to use. If you want to have Server Activation use this line of code:

RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyRemotableType),"RemotingTest.soap", WellKnownObjectMode.Singleton);
Console.WriteLine("Remote server started ...\r\nPress enter to stop");
Console.ReadLine();

Notice that in line above I used the Singleton but you can change it to SingleCall, also.You can also use RegisterActivatedServiceType . Notice that here in server application I used ReigsterXXXXServicesType
but in the client side you have to use RegisterXXXXClientType. And I also passed a name for this channel " RemotingTest.soap", this name is used to find the remote channel.

Part 3: Client Application
Now I want to use MyRemotableType and create instance from that but as a remote object. To do this first I add a reference to my MyRemotableTypes.dll. The I have to set the channel in my client application. I do this by using the RegisterWellKnownClientType method of RemotingConfiguration, as I said before.

RemotingConfiguration.RegisterWellKnownClientType(typeof(MyRemotableType),"http://RemoteServerName/RemotingTest.soap");

But notice that you give the type you want to use by remoting and also the url of remote server as parameters.
Now try to create some objects from the MyRemotableType.

MyRemotableType t = new MyRemotableType();
t.AddNumbers(10,10);
Console.WriteLine(t.CaldSum(10,10));

Part 4: Test the Applications
Now for testing the application, first run the Server Application,then while the server is running start the client application. And see the result.

As you may see, you will get just one line printed in client :

Sum is: 20


But in server side you got two printed line:
A New MarshalByRefObject created
ُS um is: 20

It means that you the object is created on server and the first method call is Writing to Console of server, but the result of method is accessible in client.

It will discuss more about remoting in my next posts.
You can download the sample code at:
http://www.tabatabaei.info/csharpsamples/firstremoting.rar

2 comments:

Anonymous said...

لينكش كارنميكنه

Masoud Tabatabaei said...

Please check it now.