如何判断其他应用程序是否已注册 IPC 远程通道?

发布于 2024-08-05 13:08:57 字数 318 浏览 6 评论 0原文

所以我有一个具有 .NET API 可用的应用程序。他们的 API 库通过 .NET 远程调用与主应用程序进行通信。为了使用 API,应用程序必须已启动并运行。

因此,我有一个实例,需要以编程方式启动应用程序,然后实例化一个 API 对象,该对象尝试打开主应用程序的 IPC 远程处理通道。问题是,在我启动进程后,启动和应用程序注册通道之间有几秒钟的时间。如果我尝试在注册通道之前实例化 API 对象,它就会消失。

我对 .NET 远程处理知之甚少,这也无济于事。

如何从使用其 API 的我的应用程序确定其应用程序是否已注册通信通道,以便我知道可以实例化其 API 对象?

So I have an application which has a .NET API available. Their API library communicates with their main application through .NET remoting calls. In order to use the API, the application must be up and running already.

So, I have an instance where I need to programmatically start the application and then instantiate one of the API objects, which attempts to open an IPC remoting channel to the main app. The problem is, after I start the process, there are a few seconds between startup and when the application registers the channel. If I try to instantiate an API object before the channel is registered, it biffs out.

It doesn't help that I know very little about .NET remoting.

How do I determine from MY application which uses their API if THEIR application has registered the channel for communication so I know it's okay to instantiate their API object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅浅 2024-08-12 13:08:57

试试这个:

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

传入端口,你应该得到一个值,指示该端口上是否有侦听器。希望这有帮助

Try this:

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

Pass in the port and you should get a value indicating whether there is a listener on that port.Hope this helps

终止放荡 2024-08-12 13:08:57

只是为了暂时摆脱困境,您是否考虑过将 WCF 与 MSMQ 一起使用?我不确定我是否完全理解您的架构,但听起来 API 的客户端必须启动另一个托管 API 的进程。启动 API 主机与客户端尝试进行调用之间可能存在时间问题。 Microsoft 最近已将 .NET Remoting(以及所有其他以前的通信技术,例如 ASMX Web 服务)视为遗留技术,并强烈建议开发人员迁移到 WCF 平台。

如果将 WCF 与 MSMQ 一起使用,则不应出现计时问题。无论 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 的松散耦合和可靠的通信优势,但这肯定会减少工作量。 ;)

Just to get out of the box for a moment, have you thought about using WCF with MSMQ? I am not sure that I fully understand you're architecture, but it sounds like the client of the API has to spin up another process that hosts the API. There may be a timing issue between when you start the API host, and when the client tries to make calls. Microsoft has recently deprecated .NET Remoting (as well as all their other previous communications technologies such as ASMX web services) as legacy, and is highly recommending that developers move to the WCF platform.

If you use WCF with MSMQ, you shouldn't have a problem with timing. Your client application can drop messages in a durable queue regardless of whether the API host is running or not. The API host can be started at any time, and it will pick up and process any messages waiting in the queue. Even if you still have the client application start up the API host, the timing problem would no longer be an issue because you are using queuing to transfer the messages rather than .NET Remoting. WCF provides a nice, convenient, easy to use wrapper around MSMQ, so the barrier to entry is relatively low.

The other beautiful thing about using WCF over .NET Remoting is that you can easily move the API host to a different physical server without having to change the client app(s). You could even move to a different queuing platform if you so desired (such as RabbitMQ on AMQP), without changing either the client or API host apps. WCF handles all of that interaction for you, providing a much cleaner decoupling and more dependable communications between your client app and API host.

If moving to WCF is not an option, you should be able to explicitly set the port with .NET Remoting. I am not sure how you are configuring your API host, but the URL for any given remoted object is usually in the form of:

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

If you add the port, then you should be able to use Abhijeet's solution to determine if the port is open or not. You won't gain the loose coupling and dependable communications benefits of WCF, but it would definitely be less work. ;)

慈悲佛祖 2024-08-12 13:08:57

您是否考虑过将实例化 API 对象的尝试包装到 try-catch 块中?然后就可以分析异常,看看是否是服务器没有监听导致的。如果是,您可以等待并重试。

有道理吗?

Have you considered wrapping the attempt to instantiate API object into a try-catch block? Then you can analyze the exception and see if it was caused by the server not listening. And if it was, you can just wait and retry.

Makes sense?

倾听心声的旋律 2024-08-12 13:08:57

只是代码中的一个小错字。
更正如下:

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

Just a small typo in the code.
Correction is as follows:

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; 
} 
撕心裂肺的伤痛 2024-08-12 13:08:57

当您注册 IpcServerChannel 时,它会创建一个命名管道来与您为 IpcServerChannel 选择的端口名称进行通信。您可以查看命名管道列表以查看您的端口名称是否在那里。

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

When you register a IpcServerChannel it makes a Named Pipe to communicate over with the name of the Port Name you chose for your IpcServerChannel. You can look at the list of Named Pipes to see if your Port Name is there.

System.IO.Directory.GetFiles(@"\\.\pipe\").Any((path) => path.Contains(@"\\.\pipe\" + pipeName));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文