如何测试网络管道服务是不是正在侦听

Posted

技术标签:

【中文标题】如何测试网络管道服务是不是正在侦听【英文标题】:How can I test to see if a net pipe service is listening如何测试网络管道服务是否正在侦听 【发布时间】:2011-12-20 05:15:00 【问题描述】:

如何以编程方式测试以查看特定网络管道服务是否正在运行和侦听,因此我没有收到“没有端点正在侦听...”异常?

例如,如果我有这个代码:

Uri baseAddress = new Uri("http://localhost/something");
var _ServiceHost = new ServiceHost(typeof(Automation), new Uri[]  baseAddress );
NetNamedPipeBinding nnpb = new NetNamedPipeBinding();
_ServiceHost.AddServiceEndpoint(typeof(IAutomation), nnpb, "ImListening");
_ServiceHost.Open();

我想从另一个应用程序与http://localhost/something/ImListening 通信,但在我想确保正在侦听之前我不会收到异常,或者异常是测试这个的唯一方法吗?

【问题讨论】:

【参考方案1】:

监听异常。这正确的方法。

【讨论】:

问题是我实际上需要等待这个服务,因为我将从与它通信的相同代码启动它,所以我应该创建一些我的服务中的虚拟方法并继续调用它直到我停止收到异常? 除非您向您的服务发送大量数据,否则为什么不首先联系您尝试联系的方法? (显然,延迟重复异常) 好吧,我还不知道我会在我的服务上调用哪些方法。我也想保持频道打开,除非它失败或出现问题。也许我可以在这里使用Mutex。无论如何,我希望我的应用程序知道该服务是否已经在运行。稍后可以使用它来启用/禁用某些按钮和类似的东西。 为什么您的服务无论如何都不会运行?这会是一种常见的情况吗?如果没有,请不要担心。如果是这样,请创建另一个服务来告诉您第一个服务是否有效。【参考方案2】:

异常的存在是有原因的,我只会处理异常,只要你处理它,用户就不会收到一个神秘的错误消息,我猜这就是你想要避免的。

【讨论】:

【参考方案3】:

如果您使用ChannelFactory.CreateChannel,它会返回一个代理,该代理在不打开通信通道的情况下实现您的服务接口。但是,代理还实现了IClientChannel,您可以使用它来检查端点是否已启动。在我的情况下,我还需要等待端点启动,所以我使用了一个带有超时的循环:

public static Interface CreateOpenChannel<Interface>(Binding protocol, EndpointAddress address, int timeoutMs = 5000)

    for (int startTime = Environment.TickCount;;) 
        // a proxy is unusable after comm failure ("faulted" state), so create it within the loop
        Interface proxy = ChannelFactory<Interface>.CreateChannel(protocol, address);
        try 
            ((IClientChannel) proxy).Open();
            return proxy;
         catch (CommunicationException ex) 
            if (unchecked(Environment.TickCount - startTime) >= timeoutMs)
                throw;
            Thread.Sleep(Math.Min(1000, timeoutMs / 4));
        
    

这是用NetNamedPipeBinding 测试的。我不确定这是否会与其他绑定的行为方式相同,或者Open() 是否只是打开一个连接或还测试连接的有效性(例如,主机接口是否与客户端接口匹配)。

【讨论】:

+1 这是一种简单可靠的方式,不需要向代理添加任何额外的方法。它根据接受的答案检查异常,但在代理上使用 Open 方法是秘诀。【参考方案4】:

也许不是最好的方法,但我没有找到另一种使用NetNamedPipe 测试端点的方法。

我通常这样做:

    public void IsValid()
    
        RegisterConfiguration();

        var endPoints = Host.Description.Endpoints;
        if (!endPoints.HasElements())
        
            throw new NullReferenceException("endpoints (WCF Service).");
        

        foreach (var item in endPoints)
        
            var service = new ChannelFactory<ITcoService>(item.Binding, item.Address);
            try
            
                var client = (IClientChannel)service.CreateChannel();

                try
                
                    client.Open(TimeSpan.FromSeconds(2));
                    throw new InvalidOperationException(
                        string.Format(
                            "A registration already exists for URI: \"0\" (WCF Service is already open in some IChannelListener).",
                            item.Address));
                
                catch (Exception ex)
                
                    if (ex is System.ServiceModel.CommunicationObjectFaultedException ||
                        ex is System.ServiceModel.EndpointNotFoundException)
                    
                        Debug.WriteLine(ex.DumpObject());
                    
                    else
                    
                        throw;
                    
                
                finally
                
                    new Action(client.Dispose).InvokeSafe();
                
            
            finally
            
                new Action(service.Close).InvokeSafe();
            
        
    

(对不起,这段代码中的扩展方法,InvokeSafe 只是一个 try/catch 来执行 ActionHasElements 只是测试一个集合是否不同于 null 和空)。

【讨论】:

以上是关于如何测试网络管道服务是不是正在侦听的主要内容,如果未能解决你的问题,请参考以下文章

如何测试输出到 std::cout (连接到管道)是不是会阻塞

如何在 DevOps 上针对多个服务运行集成测试?

在 Flutter 中使用 localhost 并在 iOS 设备上进行测试

App弱网测试-QNET

如何使用 bloc 并在 dart 中手动侦听 bloc.state 而不是通过 Flutter 或 AngularDart 的 bloc 管道?

弱网测试常用工具(附链接)