2009-09-25 76 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)); 
相关问题