Remoting Client / Server Functionality separation with Interfaces

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Even though it is not a requirement for what I am doing, I would like to
create a remoting client library that does not have to reference the server
library. The recommended way of doing this is to create an intermediate
interface library and have the Server implement the interfaces and the client
retrieve a reference to the interface.

I have gotten this to work, but I had to change somethings around that I
think are less efficient. Here is what I used to do:

Server:

public class TopUpRequest : MarshalByRefObject
{
public TopUpResult Request(Int32 rtsCarrierID);
}

[Serializable]
public class TopUpResult
{
// A bunch of properties holding result information
}

Server supports SingleCall requests from client which is the most efficient
mode. I also like the fact that I serialize the result which has several
properties and hand it back to the client as read only (e.g. can't go back to
server).

Unfortunately, when I separate everything with interfaces, I can no longer
serialize the TopUpResult class and reference an interface to it from the
client, because the client throws an exception stating that it needs a
reference to the server library do deserialize. I guess this kind of makes
sense, due to the fact that the interface really doesn't know about the
private members. I can get everything to work if I don't serialize
TopUpResult, but this means that each time I fetch a property it is going
back to the server (analogous to DCOM chatter in the old days). I guess, I
could have a single method to grab all properties to be a bit more efficient.
Another idea I have is to just let TopUpResult have public members define
the interace accordingly...not sure if this will work. Anyhow the objective
is to have good code separtion without affecting the efficiency because this
needs to be as scalable as possible. Can someone make a recommendations? My
current working code looks like this:

Server:

public class TopUpRequest : MarshalByRefObject, ITopUpRequest
{
public ITopUpResult Request(Int32 rtsCarrierID);
}

public class TopUpResult : MarshalByRefObject, ITopUpResult
{
// A bunch of properties holding result information
}

Client:

m_topupRequest = (ITopUpRequest) Activator.GetObject(
typeof(RTS.Remoting.Interface.ITopUpRequest),
"tcp://" + rtsServiceIPAddress + ":" +
rtsServicePort.ToString() + "/TopUpRequest");

m_topupResult = m_topupRequest.Request(rtsCarrierID);

The client code works just fine based on the above server implementation,
but fails due to serialization issues if I define TopUpResult as follows:

[Serializable]
public class TopUpResult : ITopUpResult
{
// A bunch of properties holding result information
}
 
I used Ethereal to measure the amount of traffic for both of my solutions. I
have came to some conclusions concerning the implementations and was
wondering if you all agree:

1) TopUpResult Serializable, No Interfaces - This solution is very
efficient. The request is sent in one data packet and the result is received
in one data packet. Also, since it is SingleCall, the server does not keep
an object around and the connection closes after a short period of time if
another request is not sent. The serialized TopUpResult can be held
indeterminantly and properties can be accessed without any network
communication.

2) TopUpResult MarshalByRefObject, ITopUpRequest Interface - Even though the
TopUpRequest call is SingleCall, the TopUpResult is MarshalByRef and it will
hang around for the lifetime of the reference much like ClientActivaton. If
the reference is held around for a while, it appears that state information
is transfered back and forth between the client and server. The other
drawback is that every time you reference a property on the object, it has to
retrieve it from the server.

Larry Herbinaux said:
Even though it is not a requirement for what I am doing, I would like to
create a remoting client library that does not have to reference the server
library. The recommended way of doing this is to create an intermediate
interface library and have the Server implement the interfaces and the client
retrieve a reference to the interface.

I have gotten this to work, but I had to change somethings around that I
think are less efficient. Here is what I used to do:

Server:

public class TopUpRequest : MarshalByRefObject
{
public TopUpResult Request(Int32 rtsCarrierID);
}

[Serializable]
public class TopUpResult
{
// A bunch of properties holding result information
}

Server supports SingleCall requests from client which is the most efficient
mode. I also like the fact that I serialize the result which has several
properties and hand it back to the client as read only (e.g. can't go back to
server).

Unfortunately, when I separate everything with interfaces, I can no longer
serialize the TopUpResult class and reference an interface to it from the
client, because the client throws an exception stating that it needs a
reference to the server library do deserialize. I guess this kind of makes
sense, due to the fact that the interface really doesn't know about the
private members. I can get everything to work if I don't serialize
TopUpResult, but this means that each time I fetch a property it is going
back to the server (analogous to DCOM chatter in the old days). I guess, I
could have a single method to grab all properties to be a bit more efficient.
Another idea I have is to just let TopUpResult have public members define
the interace accordingly...not sure if this will work. Anyhow the objective
is to have good code separtion without affecting the efficiency because this
needs to be as scalable as possible. Can someone make a recommendations? My
current working code looks like this:

Server:

public class TopUpRequest : MarshalByRefObject, ITopUpRequest
{
public ITopUpResult Request(Int32 rtsCarrierID);
}

public class TopUpResult : MarshalByRefObject, ITopUpResult
{
// A bunch of properties holding result information
}

Client:

m_topupRequest = (ITopUpRequest) Activator.GetObject(
typeof(RTS.Remoting.Interface.ITopUpRequest),
"tcp://" + rtsServiceIPAddress + ":" +
rtsServicePort.ToString() + "/TopUpRequest");

m_topupResult = m_topupRequest.Request(rtsCarrierID);

The client code works just fine based on the above server implementation,
but fails due to serialization issues if I define TopUpResult as follows:

[Serializable]
public class TopUpResult : ITopUpResult
{
// A bunch of properties holding result information
}
 
Back
Top