|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Remoting Client / Server Functionality separation with Interfacescreate 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. Show quote "Larry Herbinaux" wrote: > 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 > } > |
|||||||||||||||||||||||