Frage

Wir haben ein seltsames Problem mit .NET Remoting. Grundsätzlich haben wir einen Server, der zwei TcpChannels mit ChannelServices.RegisterChannel() Register:

  1. Ein lauscht auf Port 50000
  2. Sonstige lauscht auf Port 15000.

Wir haben dann einen Client, der eine TcpChannel registriert, um mit dem Server zu kommunizieren. Wir rufen Sie ein Objekt aus dem Server von Activator.GetObject() mit dem URI-Aufruf

  

"tcp: // serverip: 50000 / objektname"

und das funktioniert gut, der Client eine Verbindung zum Server auf Port 50000 und erhält das Objekt.

Wenn wir jedoch das Aufrufen von Methoden auf diesem Objekt starten, die Verbindung zum Kanal auf Port 50000 fallen gelassen wird, und eine neue Verbindung mit dem Kanal auf Port 15000 automatisch. Dies stellt ein echtes Problem für uns, da wir nicht wollen, den Verkehr auf Port 15000, da dieser Kanal nicht in demselben Netzwerkadapter als Port 50000 Kanal auf dem Server oder diesen Port kann nicht sein, offen in der Firewall, die Ursachen gebunden sein kann die Remote Anrufe natürlich zum scheitern verurteilt.

Das ist für uns sehr seltsam, da der Kunde keine Kenntnis in unserem Code hat, dass es einen anderen Kanal auf dem Server auf Port vorhanden 15000 oder welche IP er hört auf, aber es versucht, eine Verbindung herzustellen.

Jede Hilfe zu diesem Thema ist sehr zu schätzen,

Danke, Casper

Dies ist der Code, dass Sätze auf einen der Server-Kanäle, die man in der Regel auf 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() );

Dies ist der Code, dass Sätze auf den anderen Server-Kanal, in der Regel auf 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.

Dies ist der Code in dem Client, dass eine Verbindung zu dem ersten Server-Kanal, der, die in der Regel ist auf 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);
War es hilfreich?

Lösung

Wir haben einen Support-Fall mit Microsoft über diese protokolliert und es scheint, was wir hier tun, ist nicht von .NET Remoting unterstützt. Sie sind nur einen Kanal von jedem Typ in einer Anwendungsdomäne registrieren erlaubt. Was tut Remoting ist, dass sie die URI des Objekts an den Client sendet es zu sagen, wo sie das betreffende Objekt zugreifen können. Wenn es funktioniert, dass es die registrierten Kanäle auf der Serverseite durchsucht und verwendet den ersten Kanal, dass es dort findet, dass die Art (in unserem Fall: Tcp) angefordert übereinstimmt. Mit anderen Worten wird es verwenden, was Kanal zuerst erhalten registriert passiert. Es kümmert sich nicht überhaupt zu wissen, was die Client-Kanal angeschlossen an.

Die Lösung ist Ihre eigenen IClientChannelSinkProvider auf der Client-Seite zu implementieren. Wenn Sie die CreateSink () -Methode implementieren können Sie wählen, welche URL der Client eine Verbindung herstellen möchten, wenn Sie das Waschbecken Verwendung erstellen.

Andere Tipps

Ich habe stuggle mit denen „backlinked“ Ports als auch, Ich dachte, es wäre nur occure, wenn der Server will etwas zurück senden (auch in einem Event-Verfahren). Weil ich mit den Firewalls immer wieder Probleme hatte, wechselte ich zu GenuineChannels (obwohl ich denke, das ist ein bisschen veraltet).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top