I am trying to establish a .Net remoting call to a thirdparty app. Here's the example code I have been given for that connection (With proprietary names removed):
IDictionary props = new ListDictionary();
props["port"] = 0; // have the Remoting system pick a unique listening port (required for callbacks)
props["name"] = string.Empty; // have the Remoting system pick a unique name
BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
_channel = new TcpChannel(props, new BinaryClientFormatterSinkProvider(), serverProv);
ChannelServices.RegisterChannel(_channel, true);
IThirdparty _thirdparty = (IThirdparty)Activator.GetObject(typeof(IThirdparty), "tcp://localhost:9090/Thirdparty.AppIntegration");
//Example API call
_thirdparty.Minimized = !_thirdparty.Minimized;
When this code gets called normally, it hangs at _thirdparty.Minimized
and outputs a SocketException
in the diagnostics window with the message:
No connection could be made because the target machine actively refused it
The call only returns if I close the Thirdparty app.
I checked netstat -bano
and the only app running on port 9090 is the one I am trying to connect to.
So I moved the call to the first few lines of the Main()
function in my app and it works just fine. Problem is, that's not where it's supposed to be.
My app contains a lot of other remoting calls to a different server (not on port 9090) as well as a WCF service. My guess is that one of these things are interfering.
Any ideas on how I can figure out why this remoting call never returns?
Update: I have determined that the SocketException is likely a red herring as these exceptions are created when it works in the 3rd party test app. Also, it looks like the reason why it is hanging is because it is waiting for a Socket.Read() which never gets any data.
It turns out, in .NET remoting, there can only be one TCPClientChannel per AppDomain. Activator.GetObject() uses the first channel that was registered.
The reason why this was blocking is because I already had a TCPClientChannel setup in my AppDomain. This channel had the secure set to false when it was registered. i.e.
ChannelServices.RegisterChannel(_channel, false);
The service I was trying to talk to had security enabled and therefore the remoting call would hang trying to listen to a response that would never come.
The solution is to load my integration into a new AppDomain so that I can configure the TCPChannel differently.