Pregunta

Estamos teniendo un problema extraño con .NET Remoting. Básicamente, tenemos un servidor que registra dos TcpChannels con ChannelServices.RegisterChannel():

  1. Uno escucha en el puerto 50000
  2. Otros escuchas uno en el puerto 15000.

A continuación, tiene un cliente que registra una TcpChannel a ser capaz de comunicarse con el servidor. Recuperamos un objeto desde el servidor llamando Activator.GetObject() con el URI

  

"tcp: // serverip: 50000 / objectname"

y esto bien las obras, se conecta el cliente al servidor en el puerto 50000 y obtiene el objeto.

Sin embargo, cuando comenzamos a llamar a métodos en ese objeto, la conexión con el canal en el puerto 50000 se deja caer, y una nueva conexión se realiza en el canal en el puerto 15000 de forma automática. Esto plantea un problema real para nosotros ya que no quieren que el tráfico en el puerto 15000, ya que el canal no se puede unir a la misma red que el adaptador de canal de puerto 50000 en el servidor o que el puerto puede no estar abierto en el cortafuegos, lo que provoca las llamadas de comunicación remota a fallar de forma natural.

Esto es muy extraño para nosotros ya que el cliente no tiene conocimiento en nuestro código que existe otro canal en el servidor en el puerto 15000 o lo que se escucha en IP, sin embargo, intentar conectarse a él.

Cualquier ayuda en esto es muy apreciada,

Gracias, Casper

Este es el código que configura uno de los canales de servidor, el que por lo general en el puerto 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() );

Este es el código que configura el otro canal servidor, por lo general en el puerto 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.

Este es el código en el cliente que se conecta al primer canal de servidor, el que está por lo general en el puerto 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);
¿Fue útil?

Solución

Hemos registró un caso de soporte con Microsoft acerca de este y, al parecer, lo que estamos haciendo aquí no es compatible con .NET Remoting. Sólo se le permite registrar un canal de cada tipo en un dominio de aplicación. Lo Remoting hace es que devuelve el URI del objeto al cliente que le indiquen dónde se puede acceder al objeto en cuestión. Cuando lo hace que se ve a través de los canales registrados en el lado del servidor y utiliza el primer canal que se encuentra allí que coincide con el tipo solicitado (en nuestro caso: TCP). En otras palabras, se utilizará cualquier canal que pasa a quedar matriculados por primera vez. No le importa en absoluto acerca de lo que canalizar el cliente ha conectado.

La solución es poner en práctica su propio IClientChannelSinkProvider en el lado del cliente. Cuando se implementa el método CreateSink () se puede elegir qué URL desea que el cliente se conecte a cuando se crea el fregadero para su uso.

Otros consejos

Lo hice stuggle con los puertos "backlinked" también; Pensé que sólo sería occure si el servidor quiere devolver algo (incluso en un evento del procedimiento). Porque siempre tuve problemas con los servidores de seguridad, que me pasa a GenuineChannels (aunque creo que es un poco anticuado).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top