【问题标题】:WCF: One-way callbacks timeouts after hibernationWCF:休眠后的单向回调超时
【发布时间】:2020-06-29 20:15:20
【问题描述】:

我的应用程序必须包含组件、一项服务(作为系统运行)和一个客户端(在用户空间中运行)。两者都使用 WFC (localhost) 进行通信,并且通信工作正常,直到我休眠并恢复机器。 从那一刻起,我用作心跳的方法就是抛出一个超时异常,内容如下

消息无法在分配的超时时间 00:01:00 内传输。可靠通道的传输窗口中没有可用空间。分配给此操作的时间可能是较长超时的一部分。

我正在检查连接状态并且没有故障。幸运的是,在连接“不活动”10 分钟后,另一个超时(10 分钟)到期,将连接状态更改为“故障”。在那一刻,我的客户端检测到新状态并能够重新启动连接。

我的服务器有以下配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
  <system.serviceModel>
    <bindings>
      <wsDualHttpBinding>
        <binding openTimeout="00:00:05"
                 closeTimeout="00:00:05"
                 sendTimeout="00:00:03"
                 receiveTimeout="00:01:00">
          <security mode="Message" >
            <message clientCredentialType="Windows"/>
          </security>
        </binding>
      </wsDualHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service name="EEAS.Kiosk.WcfService">
        <endpoint address="" binding="wsDualHttpBinding" contract="EEAS.Kiosk.IWcfService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/KioskService/WcfService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

我的客户有以下配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
    </startup>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IWcfService" />
            </wsDualHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8733/KioskService/WcfService/"
                binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IWcfService"
                contract="KioskWcf.IWcfService" name="WSDualHttpBinding_IWcfService">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

我的服务接口

  [ServiceContract(CallbackContract = typeof(IWcfServiceCallback))]

    public interface IWcfService
    {
        [OperationContract]
        void OpenSession();

        [OperationContract]
        CompositeType OpenSessionWithMessage();

        [OperationContract]
        bool isAlive();

        [OperationContract]
        void TemporarySuspension();
    }

以及回调接口

    public interface IWcfServiceCallback
    {
        [OperationContract]
        bool IsAlive();

        [OperationContract]
        void SuspensionFinished();

        [OperationContract]
        bool UIMessageOnCallback(CompositeType UIMessage);
    }

有什么想法吗?我唯一的解决方案是尝试将 10 分钟的超时时间减少到最低限度,以便快速检测到故障连接并重新启动。远非完美:/

【问题讨论】:

    标签: wcf timeout channel hibernation


    【解决方案1】:

    目前的场景似乎不需要双面绑定。如果使用双工模式通信,请应用单向通信,以确保客户端或服务器不会超时。

        [ServiceContract(Namespace = "sv1", ConfigurationName = "isv", CallbackContract = typeof(ICallBack))]
        public interface IService1
        {
            [OperationContract(Action = "post_num", IsOneWay = true)]
            void PostNumber(int n);
        }
        [ServiceContract(Namespace = "callback")]
        public interface ICallBack
        {
            [OperationContract(Action = "report", IsOneWay = true)]
            void Report(double progress);
    }
    

    另外,如果服务器和客户端不是同一台机器,请在调用服务时在客户端提供windows凭据。
    如果问题仍然存在,请随时告诉我。

    【讨论】:

    • 我将名为 (isAlive()) 的心跳方法设置为您提到的单向方法,但它引发了异常。似乎 OneWay 操作无法返回值,这是有道理的。 :/ System.ServiceModel.dll 中发生“System.InvalidOperationException”类型的未处理异常附加信息:标记为 IsOneWay=true 的操作不得声明输出参数、引用参数或返回值。
    • 关于是否需要双工绑定,我会尝试解释。当客户端连接时,服务将客户端显示的字符串消息推送给用户作为气球提示。此外,一旦连接,客户端就会提取配置信息。所以我认为需要双向心跳。从客户端的角度来看,如果服务关闭,只需退出执行(避免僵尸进程)。从服务的角度来看,如果客户端挂起或退出,则启动一个新的,以便消息可以继续向用户展示。我相信有一种更简洁的方法可以实现这一点。我是 WCF 的新手:/
    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 2017-10-30
    • 2022-11-07
    • 2012-03-31
    • 2018-11-05
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多