2009-09-25 75 views
5

所以我有一個應用程序有一個.NET API可用。他們的API庫通過.NET遠程調用與主應用程序進行通信。爲了使用API​​,應用程序必須已經啓動並運行。如何判斷其他應用程序是否已註冊IPC Remoting通道?

所以,我有一個實例,我需要以編程方式啓動應用程序,然後實例化其中一個API對象,它試圖打開一個IPC遠程處理通道到主應用程序。問題是,在我啓動進程之後,啓動和應用程序註冊通道之間會有幾秒鐘的時間。如果我在頻道註冊之前嘗試實例化一個API對象,它就會崩潰。

這對.NET的遠程處理知之甚少。

如果我的應用程序使用他們的API,如果他們的應用程序註冊了通信通道,我知道可以實例化他們的API對象嗎?

+0

Jon Skeet!你必須知道答案! = [ – snicker 2009-09-28 21:13:04

回答

2

試試這個:在港口

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
     IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
     IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
     if (activeListeners.Any(conn => conn.Port == port)) 
     { 
      return true; 
     } 
     return false; 
} 

通行證,你應該得到一個值,指示是否有聽衆對port.Hope這有助於

+1

問題是..它不是一個端口。它是IPC遠程處理,所以有端口「名稱」,但不是實際的端口。 – snicker 2009-09-25 16:09:47

+0

如果您正在編程創建一個偵聽連接的進程,那麼它必須在某個端口上進行偵聽。 此MSDN示例使服務器偵聽端口9090上的IPC調用: http://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcchannel.aspx 如果您不'不知道端口,嘗試從命令行運行netstat,你應該能夠看到哪些端口正在使用 – 2009-09-29 00:18:23

+0

啊,這似乎是有道理的。但是,端口隨機更改。對此有何建議? – snicker 2009-09-29 15:19:31

0

只是爲了得到開箱即用的時刻,你有沒有想過使用WCF與MSMQ?我不確定我是否完全理解你是體系結構,但聽起來像API的客戶端需要啓動另一個承載API的進程。在啓動API主機和客戶端嘗試撥打電話之間可能存在計時問題。微軟最近棄用.NET Remoting(以及其他以前的通信技術,如ASMX Web服務)作爲傳統,並強烈建議開發人員轉向WCF平臺。

如果您在MSMQ中使用WCF,您應該沒有時間問題。無論API主機是否正在運行,您的客戶端應用程序都可以將消息放入持久隊列中。 API主機可以在任何時候啓動,並且會接收並處理隊列中等待的任何消息。即使您仍然有客戶端應用程序啓動API主機,計時問題也不再是一個問題,因爲您使用排隊傳輸消息而不是.NET Remoting。 WCF圍繞MSMQ提供了一個很好的,方便的,易於使用的包裝,因此進入的門檻相對較低。

在.NET Remoting上使用WCF的另一個優點是,您可以輕鬆地將API主機移動到不同的物理服務器,而無需更改客戶端應用程序。如果您願意,您甚至可以移動到不同的排隊平臺(例如AMQP上的RabbitMQ),而無需更改客戶端或API主機應用程序。 WCF爲您處理所有這些交互操作,爲您的客戶端應用程序和API主機提供更加乾淨的解耦和更可靠的通信。

如果移動到WCF不是一個選項,您應該能夠使用.NET Remoting顯式設置端口。我不知道你如何配置你的API的主機,但對於任何給定的遠程對象的URL通常是形式:

tcp://<hostname>[:<port>]/<object> 

如果添加端口,那麼你應該能夠使用Abhijeet的解決方案確定端口是否打開。你不會獲得WCF的鬆耦合和可靠的通信優勢,但它肯定會減少工作量。 ;)

+0

WCF不是一個選項。我不控制服務器的來源。有一個以非託管語言(可能是C++)編寫的封閉源代碼應用程序和一個作爲.NET庫提供的API。該庫是創建遠程對象的。我必須使用遠程處理,即使我知道它已被棄用並且很糟糕。 – snicker 2009-10-04 18:14:01

0

你有沒有考慮包裝嘗試實例化API對象到try-catch塊?然後,您可以分析異常並查看它是否由服務器不在監聽引起。如果是這樣,你可以等待並重試。

有意義嗎?

+0

是的,但不幸的是,封閉的源代碼API寫得不好,並設置了一些靜態變量,阻止它在同一個運行時中再次實例化,而無需使用大量的反射來修復它。這將是一個討厭的解決方案。 – snicker 2009-10-04 18:16:31

+0

然後在另一個AppDomain中執行它? – 2009-10-05 13:00:16

+0

我嘗試在try-catch塊中包裝myObj = Activator.GetObject(...),測試null等。它不起作用,因爲無論服務器是否啓動,它都會返回_TransparentProxy對象。直到後來當您嘗試使用您傾斜的myObj時。在我看來,Abjiheet有正確的答案。 – IAbstract 2010-01-22 16:30:51

0

只是在代碼中的小錯字。 更正如下:

using System.Net.NetworkInformation; 
using System.Net; 
private static bool IsPortAvailable(int port) 
{ 
    IPGlobalProperties globalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
    IPEndPoint[] activeListeners = globalProperties.GetActiveTcpListeners(); 
    if (activeListeners.Any(conn => conn.Port == port)) 
    { 
     return true; 
    } 
    return false; 
} 
0

當您註冊IpcServerChannel它使一個命名管道與您選擇您IpcServerChannel端口名稱的名稱進行溝通了。您可以查看命名管道列表以查看您的端口名稱是否存在。

System.IO.Directory.GetFiles(@"\\.\pipe\").Any((path) => path.Contains(@"\\.\pipe\" + pipeName)); 
相關問題