2009-11-01 14 views
5

I in eine remoting Ausnahme lief:Remoting- und fehlendes Kanalsenken

„Dieser remoting Proxy hat keinen Kanalkörper, was bedeutet, entweder der Server keine registrierten Serverkanäle hat, die hören oder diese Anwendung hat keinen geeigneten Client-Kanal mit dem Server sprechen. "

Die Ursache ist am besten erklärt this blog entry ich gefunden:

Der zweite Fall Unbekannter ist. Dieses tritt auf, wo der Client einen -Aufruf an den Server aufruft, der Server eine Objektreferenz zurückgibt und der Client dann einen Aufruf für das referenzierte Objekt auf dem Server ausführt. Wenn das referenzierte Objekt in einer sekundären AppDomain auf Server ist, kann die obige Ausnahme ausgelöst werden. Wenn das Problem auftritt, ist es ist, weil Kanalregistrierung nur gilt für die AppDomain in dem RegisterChannel aufgerufen wird und kein Kanal in der sekundären AppDomain registriert wurde. Das Objekt Referenz zurückgegeben an den Client Punkte auf das Objekt in dem sekundär AppDomain, nicht in seine Proxy im primären AppDomain, und so gibt es keinen Kanal zwischen dem Client und dem sekundären AppDomain über die der Anruf kann bestehen. Lösung: Registrieren Sie einen -Kanal in der sekundären AppDomain in , in dem das referenzierte Objekt vorhanden ist.

Dies passt zu meinem Szenario, da ich einen Dienst habe, der Plugins in separate Appdomains lädt. Objektinstanzen (Implementierungen einer Schnittstelle, die in einer Assembly definiert ist, auf die alle Assemblys verweisen) werden in den sekundären Appdomains erstellt und vom Dienst referenziert (Cross-App-Domäne, sodass der Service Proxyverweise hat). Der Dienst gibt dann diese Proxyverweise an eine Anwendung zurück. Es gibt registrierte Kanäle zwischen der Anwendung und dem Dienst, aber nichts zwischen dem Plugin und der Anwendung.

Ich dachte, dass ein Proxy ausreichen würde, um die appdomain Grenzen zu überschreiten. Muss ich wirklich Kanäle zwischen den Plugins und der Anwendung erstellen? Das scheint überhaupt nicht richtig zu sein, also muss ich etwas verpassen.

Antwort

2

Um Remoting über Appdomains für Objekte zu verwenden, die von MarshalByRefObject abgeleitet sind, müssen an beiden Enden Kanäle erstellt werden. Daher müssen Sie Kanäle in jeder App-Domäne erstellen. Es gibt effiziente Kanäle, um dies lokal auf derselben Maschine zu tun, z.B. der IPC-Kanal (verwendet Named Pipes).

Wenn die Kommunikation "unidirektional" ist, in dem Sinne, dass nur eine der Seiten Methoden auf Proxys aufruft, registrieren Sie hier einen Client-Kanal und den Server-Kanal auf der Seite, die die Objekte erstellt.

Falls Sie beide Wege gehen müssen, z.B.passiert ein Logging-Objekt an den „Server“, um einen kontinuierliches Protokoll Feedback zu erhalten, müssen Sie einen Serverkanal an beiden Enden registrieren, als plötzlich der Client auch Objekte dient: auf @ RonCohen Antwort

class MyLogger : MarshalByRefObject 
{ 
    public Log(string text) { ... } 
} 

MyLogger logger = new MyLogger(); 
proxyObj.LongRunningCommand(logger); 
3

zu erweitern -

auf dem Server erzeugt man in der Regel einem vollen Kanal die unterhaltsame Art und Weise (vor allem, wenn Sie das Problem TypeLevelFilter ala https://stackoverflow.com/a/9268223/344638 beheben mögen):

BinaryServerFormatterSinkProvider serverProvider; 
BinaryClientFormatterSinkProvider clientProvider; 
Hashtable properties = new Hashtable(); 

serverProvider = new BinaryServerFormatterSinkProvider(); 
serverProvider.TypeFilterLevel = TypeFilterLevel.Full; 

clientProvider = new BinaryClientFormatterSinkProvider(); 

properties.Add("port", 8080); 

this.chan = new TcpChannel(properties, clientProvider, serverProvider); 

ChannelServices.RegisterChannel(this.chan, true); 

Können sagen, Sie verwenden einen Sponsor auf der Client-Seite. Wenn Sie dies nicht tun, und der Kunde ruft nicht das remoted Objekt für eine Weile, fällt der Server das Objekt:

Object '/70c96e17_02a8_4e1a_a040_7b671b4a66b4/3fssua+asfozgeqqkrjql+4k_1.rem' has been disconnected or does not exist at the server. 

Sie sind also einen Sponsor verwenden, die der Server ruft dann gelegentlich zu erneuern das entfernte Objekt Aber! Jetzt hat der Server ein Remoted-Objekt - der Sponsor wird auf die Serverseite weitergeleitet, wenn der Sponsor ILease.Register aufruft. Wenn der Server jedoch keinen Remoting-Kanal zum Client hat, schlägt dies fehl.

So muss der Server einen Remoting-Kanal für den Client bereitstellen, damit der Client auf Remoted-Objekte zugreifen kann. Der Client muss dem Server einen Remoting-Kanal verfügbar machen, damit der Server remote zugreifen kann Objekte wie Sponsoren. Am Ende haben sowohl meine Client- als auch meine Serverseite den gleichen Kanalaufbaucode (oben), außer dass ich auf jeder Seite unterschiedliche Portnummern verwende.

0

Für diejenigen, die auf der Suche nach "Dieser Remoting-Proxy hat keine Kanalsenke ..." Fehler, habe ich diesen Fehler beim Aufruf einer VB.NET COM Wrapped Library aus VBScript. All dies befand sich auf demselben Windows 7-Computer, sodass es keine Probleme mit dem Client-Server geben sollte. Irgendwann habe ich herausgefunden, dass der Fehler dadurch verursacht wurde, dass ich eine Ladung mit Strings gefüllter Arraylisten anstatt mit Singles gefüllt hatte, was die Funktion war, die ich anrief. Ich verstehe nicht, warum ich diesen Fehler bekommen habe, aber hoffentlich hilft es jemandem, diesen Fehler zu bekommen.