WWW Yariv Hammer's Code Site

Friday, October 21, 2005

Calling Remoting Objects- Basic Concepts

MarshalByRef and Serializable
If you want to access an object in the server - that is to activate its methods and properties, you must inherit the class from MarshalByRefObject. This is because in the client you only have a reference to that object and a proxy is created for you.
However, sometimes you just want to pass information between the server and the client in the form of objects. This objects will be serialized, sent to the other process (maybe other computer) and de-serialized in the remote process. All the internal information in these kinds of objects is passed, and each method and property you call in the remote process is done in that process. For this kind of behavior you must either set the Serializable attribute, or implement the ISerializable interface.
So how can you pass an object by value between the server and the client? You need one object in the server to inherit from MarshalByRefObject with a method that returns the Serializable object, or that get a Serializable object as parameter, That way objects are passed by value between the client and the server.

Singlecall and Singleton
Now that the issue of MarshalByRef and Marshal by value is settled, lets investigate how we can tell the server not to keep state of marshaled by reference objects, or in other words Stateless objects. There are two types of ways the client can use Remote objects (marshaled by reference): Singleton or SingleCall. The first will create one instance that all the clients call. This object will be with state that will be kept between calls. The second will act as a service - It does not remember state between call, each time a client tries to call a method or property it calls a new instance in the server.

Shared Assemblies
Ok, now I will explain what shared assemblies are all about. In order for an object to be called remotely, and it does not matter whether it is marshaled by reference or serializable, both client and server must know of this object. Why? simply because the client (for example) can't access class X's method without it having a definition for the class and its method. So what we need is to have a dll (class library) with all the common objects to both server and clients - all the MarshalByReference and Serializable objects should be in that assembly. Both Server and Client executables should have a reference to that dll.

Using Interfaces For MarshalByRef Objects
But this is quite bad. We don't want the client to have the implementation of the server's objects and the other way around. That's when interfaces come to the rescue. In the shared assembly we will put only interfaces and classes that it is ok to share. The client and server will only know of this interfaces. The actual classes which implement the interfaces will be in the client/server assemblies, but the other will not know of them. So we don't need to deploy server classes in the client - just a dll with interface which is also deployed with the server. This discussion is not relevant to objects which are passed between processes by value (Only MarshalByRefObjects).

In the next post I will show a simple example of how to set up a server and client, with a shared assembly and configuration file, using interfaces and both MarshalByRefObjects and Serializable objects.


Post a Comment

<< Home

Feel free to use everything here. Add links to my site if you wish.

Do not copy anything to other sites without adding link to here.

All the contents of the site belong to Yariv Hammer.