WCF: таймауты односторонних обратных вызовов после гибернации - PullRequest
0 голосов
/ 18 марта 2020

Мое приложение имеет компоненты, один сервис (работает как система) и один клиент (работает в пространстве пользователя). Оба обмениваются данными с помощью WF C (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-минутный тайм-аут до минимума, чтобы неисправное соединение было быстро обнаружено и перезапущено. далеко не идеально: /

1 Ответ

0 голосов
/ 19 марта 2020

Не похоже, что текущий сценарий требует дуплексного связывания. При использовании связи в дуплексном режиме используйте одностороннюю связь, чтобы гарантировать, что время ожидания клиента или сервера не истекло.

    [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 учетные данные на стороне клиента при вызове службы.
Не стесняйтесь сообщить мне, если проблема все еще существует.

...