Поделиться через


.Net Remoting continued

After several frustrating hours troubleshooting issues with objects flowing in both directions (i.e., From Client to Sever and vice versa), I have some more information that may help you. This information is a continuation of the previous post on the subject found here.

 

In my previous posting I was primarily discussing activation of Client objects from a Server. I have also found something interesting about the communication between a Client and a Server over a remoting Channel, where a client object is accessed from a Server (i.e., not activated by the Server but proffered up from the Client to the Server over the remoting channel).

 

Is this confusing enough? Let’s use some pseudo-code to demonstrate the scenarios.

In the previous posting we spoke to the following scenerio.

 

  1. A Host process (let’s call this the “Client”) creates a remoting channel (IPC, TCP)

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();

System.Collections.IDictionary props = new System.Collections.Hashtable();

props["portName"] = “SomeName”;

ichannel = new IpcChannel(props, clientProvider, serverProvider);

  1. The Host/Client starts another process (let’s call this the Server)
    1. The Server application creates a remoting channel

ichannel = new IpcChannel(props, clientProvider, serverProvider);

    1. The Server publishes a local MarshalByRefObject object (MBRO). Let’s call this ServerObject

RemotingServices.Marshal(ServerObject, @"UniqueIdentifier");

Or RegisterWellknownServiceType

  1. The Client activates the ServerObject and makes calls on the methods

ServerObject serverObj = (ServerObject)Activator.GetObject(Type.GetType(AssemblyQualifiedNameOfObject), @"ipc://" + @"UniqueIdentifier"+ @"/ServerObject"));

serverObj.CallAMethod();

 

  1. If the Sever wishes to activate a MBRO in the Client process we need the following;

    1. The Client needs to create a server provider remoting channel
    2. The Client needs to publishes a local MBRO. Let’s call this ClientObject.
  2. The Server activates the ClientObject and now makes calls on the methods

     

In order to enable this two-way activation we need to set the typeFilterLevel to Full.

props["typeFilterLevel"] = "Full";

ichannel = new IpcChannel(props, clientProvider, serverProvider);

 

In the previous scenerio the Server can create MBRO’s and the Client can access the object methods over the channel. In a new scenerio, where the Client creates a MBRO object and attempts to pass the object to a Server Object, you will receive the following error message – “Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot be accessed.”

 

Note that this new scenerio the Server is not “activating” the Client object, but rather passing it to a Server object. Surprisingly, even though you have a channel established and you can call in one direction (Client calling on the Server), with an object that is MBRO, it fails. Doh!

 

We determined that we needed the typeFilterLevel property to be set to “Full” for the Server activating a Client object in the first scenerio. In this second scenerio, we also need to set the following;

serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

 

Go figure <shrug>

 

It is apparent that there is a difference between the

["typeFilterLevel"] = "Full" property

and

the Serverprovider setting

BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

 

I am not sure why these seemingly similar settings behave differently, but they do. This may be a bug or intended behavior. If I receive an answer on why they differ, I will post my findings. In any event, I thought this might save someone else the frustration I experienced and also clear up my last posting where I insinuated that these settings are interchangeable. And besides, you now you have another two-way remoting scenerio to add to your bag of tricks.

Comments

  • Anonymous
    December 14, 2006
    I do the same thing in one of my apps. It's great for removing the need for polling in the client - the server can just call methods on the client whenever something the client is interested in happens.

  • Anonymous
    December 20, 2006
    In this posting there are two sets of items 1,2,3. Are they both part of the solution or alternative ways of setting up a two way channel?

  • Anonymous
    December 20, 2006
    Mark, If I understand your question correctly, I have shown 2 distinct methods of a "two-way" channel. The first scenerio shows the Server process activating an object in the Client process.  Note that this is activating an object, not passing an object through another object. The second scenerio shows a calling convention where a Client object (i.e., An object created in the Client process) is passed to the server object (i.e., An object instantiated in the Server Process) where the server can then call on the Client Object. Make sense?

  • Anonymous
    January 16, 2007
    Hi, I am trying out the two way remoting. I want to pass an object to server from client. I want the server call a method of that client object. I have created a class which both client and server understand. The client creates a instance of that class. In one remoting method, the client tries to call a method of remoting server and passes the object to server. But here the call fails. Any pointer to solution of this problem?

  • Anonymous
    January 16, 2007
    Hi Jeevan, I'm not sure I understand your scenerio. I can't determine whether you are expecting the client and/or Server to instantiate an object in both of the others process.  If this is the case then you need another channel to handle the incoming call. If you want the Server to instantiate an object on the Client (i.e., not passing it through an object already registered over a channel) then you will need another channel registered on the client to handle the incoming calls from the Server.  So you will have 3 channels - 1 for the Server and 2 for the Client. Else, if a client is activating an object that the Server has registered with the RemotingServices for Marshalling, then you need a channel in the server process and one in the client process.  If you wish to pass an object to the server from the client you can create the object (I assume it is MBRO) on the client and pass it to the Server object as a parameter to the Server object, then the Server can make calls on the client object. Then again your scenerio may not be as described above ;-) and your issue may be related to the typefilter settings I described. I realize my posts may have left a little to the imagination, so if I receive enough demand (the squeaky wheel gets the attention), I may spend the time working up some sample code.

  • Anonymous
    February 03, 2007
    Hey Jack, Do you have sample code which i can try?? Its really hard to find an example of how to make two way communication over IPC:( I dont want the client to keep polling the server. it would be really great if you can post a sample code. Thanks Vibhore

  • Anonymous
    February 12, 2007
    A sample that show how to implementthe second #1 a., b. and 2 would be great. since it is not clear how to create the server channel and publich the local MBRO in the client. Client call to server works but the other way? ---

  • Anonymous
    February 23, 2007
    Vibhore, Look into remoting C# events. It's a little tricky but provides an elegant way to handle subscriber/publisher scenarios.

  • Anonymous
    January 31, 2008
    I followed the steps mentioned by you but still not able to communicate both ways. The requirement of my project is that client calls the methods on server and also server calls a method on client. I tried passing client object to server but server cannot call the client. It would be great help if you could provide a sample working code so that I can learn from it and know where I am going wrong

  • Anonymous
    February 01, 2008
    The comment has been removed

  • Anonymous
    February 03, 2008
    Hi Jack, Could you please tell me how would i make the communication between two processes using IPC channel. Basically i want to pass the data between processes where server is one process and clients are several. Server should identify which message is belong to which client. Thanks, Paresh

  • Anonymous
    February 04, 2008
    The comment has been removed