WCF 服务命名管道故障

Posted

技术标签:

【中文标题】WCF 服务命名管道故障【英文标题】:WCF service named pipe failure 【发布时间】:2016-08-05 04:30:09 【问题描述】:

我已经彻底搜索,找到了这个问题的几个答案,但没有一个适用。

我有一个由 Windows 服务使用命名管道端点托管的 .NET 4.0 WCF 服务。这设置为在启动时自动启动。我有一个使用该服务的客户端。

服务端重启后服务会正常启动,但是客户端会报如下错误:

1:在 net.pipe://localhost/WCFSQLService/ 上没有可以接受消息的端点侦听。这通常是由不正确的地址或 SOAP 操作引起的。有关详细信息,请参阅 InnerException(如果存在)。

2:在您的本地计算机上找不到管道端点“net.pipe://localhost/WCFSQLService/”。

如果客户端和服务都重新启动,问题就会自行解决。

正如其他人所指出的,Net.Pipe 侦听器适配器都在运行并且 WCF 非 HTTP 激活被检查:

我们甚至尝试将服务设置为延迟启动,但没有任何乐趣。有人会认为端点或配置或正常的 WCF 东西有问题,但是当服务和客户端都重新启动时,一切正常。此外,这只发生在一台机器上。如有必要,我可以提供端点信息和代码。

客户:

NetNamedPipeBinding binding = new NetNamedPipeBinding();
EndpointAddress endpoint = new EndpointAddress(endpointAddress);
ChannelFactory<IWCFSQLService> channel = new ChannelFactory<IWCFSQLService>(binding, endpoint);
IWCFSQLService client = channel.CreateChannel();
// do client calls
channel.Close();

主持人

  class Program
  
    static void Main(string[] args)
    
      ServiceBase[] servicesToRun = new ServiceBase[] 
        
          new WinServiceHost(), 
        ;


      ServiceBase.Run(servicesToRun);
    
  



  public class WinServiceHost : ServiceBase
  
    private readonly ServiceManager serviceManager = new ServiceManager();

    protected override void OnStart(string[] args)
    
      base.OnStart(args);

      serviceManager.OpenHost<MyService>();
    

    protected override void OnStop()
    
      base.OnStop();

      serviceManager.CloseAll();
    
  

  public class ServiceManager
  
    private readonly List<ServiceHost> serviceHosts = new List<ServiceHost>();

    public void CloseAll()
    
      foreach (ServiceHost serviceHost in serviceHosts)
      
        serviceHost.Close();
      
    

    public void OpenHost<T>()
    
      Type type = typeof(T);
      ServiceHost serviceHost = new ServiceHost(type);
      serviceHost.Open();
      serviceHosts.Add(serviceHost);
    
  

配置

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="behaviorConfig" name="MyService">
        <endpoint address="" binding="netNamedPipeBinding" bindingConfiguration="clientNamedPipeBinding"
                  contract="IMyService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/MyService" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <netNamedPipeBinding>
        <binding name="clientNamedPipeBinding">
          <readerQuotas maxArrayLength="65536" maxBytesPerRead="65536" />
        </binding>
      </netNamedPipeBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="behaviorConfig">
          <serviceMetadata httpGetEnabled="false" httpGetUrl="" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="true" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="SuccessOrFailure" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

【问题讨论】:

您是否尝试过在服务端开启 WCF 诊断? 客户端和托管 WCF 服务的 Windows 服务在同一台机器上,对吗? (我希望如此,因为您使用的是命名管道,但永远不知道。)。 正确,客户端和服务器在同一台机器上。我还要打开服务诊断。 只有在服务器重启时才会出现这种情况?服务器启动后客户端启动的速度有多快?它可以在 Windows 服务启动 WCF 服务之前启动吗?还是它以某种方式保留了频道的“旧”实例(我不确定它会如何做到这一点,但我想我还是会问)? 可能是这样,但是客户端会为每次调用创建、打开和关闭通道,因为它是无状态的。因此,即使确实如此,我也希望它在服务启动之前只能失败几次调用。此外,客户端必须由用户启动,因此在 Windows 服务启动之前进行调用似乎不太可能。 【参考方案1】:

也许服务器正在杀死命名管道?尝试定期在客户端上重新打开通道,直到它恢复为止。

【讨论】:

我实际上正在为每次通话关闭和重新打开频道,所以那里也没有乐趣。

以上是关于WCF 服务命名管道故障的主要内容,如果未能解决你的问题,请参考以下文章

使用命名管道 WCF 服务时通信对象出错

WCF 命名管道最小示例

未找到 WCF 命名管道端点

从 VB6 到 WCF 的命名管道

保护 WCF 使用的命名管道

与命名管道和 WCF 服务的进程间通信:线程问题