Domanda

Stiamo avendo un problema strano con .NET Remoting. In sostanza, abbiamo un server che registra due TcpChannels con ChannelServices.RegisterChannel():

  1. Un ascolto sulla porta 50000
  2. Altre ascolti uno sulla porta 15000.

Abbiamo poi un cliente che registra un TcpChannel per essere in grado di comunicare con il server. Recuperiamo un un oggetto dal server chiamando Activator.GetObject() con l'URI

  

"tcp: // serverip: 50000 / nomeoggetto"

e questo funziona bene, il collega client al server sulla porta 50000 e ottiene l'oggetto.

Tuttavia, quando abbiamo iniziare a chiamare i metodi su tale oggetto, la connessione al canale sulla porta 50000 è caduto, e un nuovo collegamento è fatto per il canale sulla porta 15000 automaticamente. Questo pone un vero problema per noi, visto che non vogliono il traffico sulla porta 15000, perché il canale non devono essere vincolati alla stessa scheda di rete come il porto canale 50000 sul server o che la porta non può essere aperta nel firewall, che le cause le chiamate remoti a fallire in modo naturale.

Questo è molto strano per noi, visto che il cliente non ha alcuna conoscenza nel nostro codice che esiste un altro canale sul server sulla porta 15000 o quello IP è in ascolto su, tuttavia tentare di connettersi ad esso.

Qualsiasi aiuto su questo è molto apprezzato,

Grazie, Casper

Questo è il codice che imposta uno dei canali del server, quello di solito sulla porta 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() );

Questo è il codice che imposta l'altro canale del server, di solito sulla porta 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.

Questo è il codice nel client che si connette al server di primo canale, quello che di solito sulla porta 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);
È stato utile?

Soluzione

Abbiamo loggati un caso di supporto con Microsoft su questo e apparentemente, quello che stiamo facendo qui non è supportato da .NET Remoting. È consentito soltanto a registrare un canale di ogni tipo in un unico dominio di applicazione. Ciò che fa è Remoting che rimanda l'URI dell'oggetto al cliente di indicare dove si può accedere l'oggetto in questione. Quando lo fa che guarda attraverso i canali registrati alla fine del server e utilizza il primo canale che si trova lì che corrisponde al tipo richiesto (nel nostro caso: Tcp). In altre parole userà qualunque canale capita di ottenere registrato prima. Essa non si preoccupa affatto di quale canale il cliente ha collegato via.

La soluzione è quella di implementare il proprio IClientChannelSinkProvider sul lato client. Quando si implementa il metodo CreateSink () si può scegliere quello url si desidera che il client di connettersi a quando si crea il lavandino per l'uso.

Altri suggerimenti

Ho fatto stuggle con quelle porte "backlink" pure; Ho pensato che sarebbe occure solo se il server vuole inviare qualcosa di nuovo (anche in un evento-procedura). Perché ho avuto sempre problemi con i firewall, ho passato a GenuineChannels (anche se credo che sia un po 'obsolete).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top