I previously wrote about bi-directional remoting over IPC (see .Net Remoting continued and .Net Remoting). Several people asked for complete sample code. Ok, the squeaky wheel gets the attention. This could be an indication of my poor writing skills 😉 or the difficulty in figuring out remoting, or a little of both.
I also want to let you know that if you are a Host or ISV providing extensibility (in or out of process), I highly recommend utilizing the BCL’s Add-In model instead of rolling your own. Particularly, in lieu of using the sample app I am attaching. I left a lot of out!!! The code is more likely appropriate as an understanding of some principles or as an internal implementation (i.e., Not for 3rd party extensibility). In the current Orcas CTP (I’ll post more on this) we have added out of process support to the System.AddIn BCL!!!
Two Way Communications
First, I want to let you know that in putting together this sample application I discovered I was wrong (don’t tell anyone) about the need to create another channel for handling incoming calls in addition to outgoing calls. Both IPC and TCP work with a single channel. Most of the issues had to do with that pesky typefilter. I guess none of the Indigo team members read my blog because no one corrected me. Hey, wait a minute. If no one noticed I was wrong and I corrected my mistake, I was only mistaken, not *wrong*.
I will show sample code of a remote object method invocation from a Host to a Remote app and vice versa. You may think in terms of a client and server if you wish, but I created so many samples that it became very confusing when an app worked like a client and a server, so I chose HostApp and RemoteApp as terms.
I also want the reader to know that a two way remoting method, whereby a Host instantiating an object, utilized for a remote process to call into and (i.e., not OR) vice versa is not a typical scenerio.
In a Host to Add-In model and in many other mainstream scenarios, the need to enable two-way method invocation in *both* the Server and Client is rare.
The typical way a “two-way” communication takes place is when one side (Client or Server) instantiates the others object and then uses that object to pass Serializable or MarshalByRef objects to the methods of the instantiated object. Or you instantiate a local, remotable object, that is called into from the remote application but rarely combinations of the two. In other words, the typical method employed is to instantiate (e.g., new) your object locally and as long as the object can be Marshaled, it is just passed to the remote client or server over an existing remoting channel via an objects method that takes the remotable object as a parameter. It may be hard to tell but I did try to make all that clear L I think the samples and the comments may make it clearer.
· I have included an example of an IPC and TCP remoting channel.
· I used the Binary formatter since it is the most efficient.
· Notice the typefilter settings I blogged about.
· Remote method invocation may be accomplished in several ways
o via RemotingServices.Marshal // which is what I did in the sample
o via a config file and RemotingConfiguration.Configure(@"C:\blah \Client.exe.config", false); // I have prototyped this method successfully
o via RemotingConfiguration.RegisterWellKnownServiceType // I had issues with this method. Read as – Good luck with that.
Check out a previous blog post on this subject
Remoting channels are only needed for Cross Process remote AppDomain communications. In process, cross AppDomain calls do not require a remoting channel.
You may not wish to run code in a remote processes default AppDomain. So I added a more complex example of a remote process, non-default AppDomain, since this is another tricky bit to work out when doing remoting. When running a “server/Host” In-process you don’t a channel per AppDomain, just a primary channel to handle incoming and outgoing calls. But for AppDomains in a remote process you need a channel per AppDomain for the calls.