2009-11-01 45 views
5

我跑進一個遠程異常:遠程處理和丟失的信道接收器

「這個遠程代理不具有信道接收器,這意味着在服務器具有被監聽沒有註冊的服務器信道,或該應用程序沒有合適的客戶端的信道與服務器交談。「

原因是最好的解釋this blog entry我發現:

第二種情況是比較模糊的。這個 發生在客戶端向服務器發出呼叫 ,服務器返回 對象引用,然後客戶端 在服務器上的引用對象 上發起呼叫。如果引用的 對象位於 的輔助AppDomain上,則服務器上述例外情況可能會引發 。如果發生問題 是因爲通道註冊僅適用於AppDomain,其中 RegisterChannel被調用,012xx通道已被註冊到 輔助AppDomain中。對象 引用返回給客戶端 指向的對象在二次 的AppDomain,而不是它的代理在 主應用程序域,並且因此存在在客戶機和 次級的AppDomain之間沒有 信道有一個使 呼叫可以通過。解決方案:在 的輔助AppDomain中註冊一個 通道,該參考對象存在。

這符合我的情況,因爲我有一個將插件加載到單獨的應用程序域中的服務。對象實例(由所有程序集引用的程序集中定義的接口的實現)在輔助應用程序域中創建,並由服務(跨應用程序域,因此該服務具有代理引用)進行引用。該服務然後將這些代理引用返回給應用程序。在應用程序和服務之間有註冊的通道,但插件和應用程序之間沒有任何通道。

我認爲代理將足以跨越應用程序邊界。我真的必須在插件和應用程序之間創建渠道嗎?這看起來並不正確,所以我必須錯過一些東西。

回答

2

爲了在從MarshalByRefObject派生的對象上的appdomains之間使用遠程處理,有必要在兩端創建通道。因此,您必須在每個AppDomain中創建頻道。在同一臺計算機上本地進行這種操作是有效的。 IPC通道(使用命名管道)。

如果通信是「單向」,就意味着只有一方正在調用代理方法,您在此註冊一個客戶端通道,並在創建對象的一側註冊服務器通道。

如果您需要兩種方式,例如爲了傳遞一個日誌對象的「服務器」,以獲得連續的日誌反饋,你必須在兩端註冊服務器通道,作爲客戶端突然也供應對象:

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

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

爲了擴大對@ RonCohen的答案 -

在服務器上,人們通常會創建一個完整的通道有趣的方式(尤其是如果你要修復的TypeLevelFilter問題ALA https://stackoverflow.com/a/9268223/344638):

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); 

比方說,你正在使用在客戶端的贊助商。如果不這樣做,並在客戶端不調用了一會兒遠程對象,服務器將刪除對象:

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

讓你在使用一個贊助商,該服務器,然後偶爾調用續約遠程對象。但!現在服務器有一個遠程對象 - 當發起人呼叫ILease.Register時,發起人得到遠程服務器端。但是,如果服務器沒有遠程處理客戶端通道,則失敗。

因此,與服務器必須向客戶端公開遠程通道以使客戶端訪問遠程對象的方式相同,客戶端必須向服務器公開遠程通道,以便服務器能夠訪問遠程對象贊助商。最後,我的客戶端和服務器端最終都具有相同的通道構建代碼​​(上面),除了我在每邊使用不同的端口號。

0

對於那些在「此遠程代理沒有通道接收器...」錯誤的搜索,我從VBScript調用VB.NET COM包裝庫時出現此錯誤。所有這些都在同一臺Windows 7機器上,所以應該沒有客戶端服務器問題。最終我發現這個錯誤是由於我傳遞了一堆充滿字符串的數組列表,而不是充滿單身,這正是我所稱呼的功能所期待的。我不明白爲什麼我得到這個錯誤,但希望它可以幫助有人得到這個錯誤。