.NET Remote Channel Switching on Your Own

We have a strange problem with .NET Remoting. Basically, we have a server that registers two TcpChannels using ChannelServices.RegisterChannel() :

  • One is listening on port 50,000
  • Another is listening on port 15000.

Then we have a client that registers TcpChannel to be able to communicate with the server. We retrieve the object from the server by calling Activator.GetObject() with a URI

"TCP: // ServerIP: 50000 / object_name"

and it works great, the client connects to the server on port 50000 and receives the object.

However, when we start calling methods on this object, the connection to the channel on port 50000 is dropped, and a new connection to the channel on port 15000 is automatically established. This creates a real problem for us, because we do not want traffic on port 15000, because this channel cannot be bound to the same network adapter as port 50000 on the server, or this port cannot be opened in the firewall, which causes remote calls to fail naturally.

This is very strange for us, because the client does not know in our code that another channel exists on the server on port 15000 or what IP address it listens to, but it tries to connect to it.

Any help on this is greatly appreciated.

Thanks Casper

This is the code that installs one of the server channels, usually on port 50000:

 IDictionary props = new Hashtable(); props["port"] = m_tcpPort; props["name"] = String.Empty; BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); m_tcpChannel = new TcpServerChannel( props, /*clientProvider,*/ serverProvider ); ChannelServices.RegisterChannel( m_tcpChannel, false ); m_wellKnownObjRef = RemotingServices.Marshal( this, "Server@" + m_tcpPort.ToString() ); 

This is the code that sets up another server channel, usually on port 15000:

 IDictionary props = new Hashtable(); props["name"] = String.Empty; props["port"] = ip.Port; props["bindTo"] = ip.Address.ToString(); props["timeout"] = REMOTING_TIMEOUT; // Timeout to prevent hung remoting calls. if (!String.IsNullOrEmpty( machineName )) { props["machineName"] = machineName; } BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); m_channel = new TcpChannel( props, clientProvider, serverProvider ); ChannelServices.RegisterChannel( m_channel, false ); m_objRef = RemotingServices.Marshal( this, QueueName ); // Queuename is a GUID. 

This is the code in the client that connects to the first server channel, which is usually located on port 50000:

 IDictionary props = new Hashtable(); props["port"] = 0; RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off; BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider(); serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider(); m_tcpChannel = new TcpClientChannel(props, clientProvider/*, serverProvider*/); ChannelServices.RegisterChannel(m_tcpChannel, false ); string address = "tcp://" + profile.RemoteIP + ":" + profile.RemoteTCP; m_server = (Kernel)Activator.GetObject(typeof(Server), address + "/Server@" + port); 
+7
c # remoting channels
source share
2 answers

We have registered a support message with Microsoft, and obviously what we are doing here is not supported by .NET Remoting. You are allowed to register only one channel of each type in one AppDomain domain. What Remoting does is that it sends the object URI to the client to tell it where it can access the object in question. When he does this, he looks at the registered channels on the server and uses the first channel found there, which corresponds to the requested type (in our case: Tcp). In other words, he will use any channel to register first. In fact, it doesn't matter what channel the client is connected about.

The solution is to implement your own IClientChannelSinkProvider on the client side. When you implement the CreateSink () method, you can choose which URL you want to connect to the client when creating the receiver.

+7
source share

I also disconnected from these "backlinked" ports; I thought that this would only happen if the server wants to send something back (even to the event procedure). Since I always had problems with firewalls, I switched to GenuineChannels (although I think I'm a bit outdated).

0
source share

All Articles