WCF Не правильно?

У меня проблема с тайм-аутом, это детали:

Конфигурация привязки выглядит следующим образом:

<netTcpBinding>
 <binding name="WindowsServerOverTcp"
   maxReceivedMessageSize="10000000"
   maxBufferSize="10000000"
   maxBufferPoolSize="10000000"
   closeTimeout="00:00:03"
  openTimeout="00:00:03"
  sendTimeout="00:00:03"
  receiveTimeout="00:00:03">
  <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
  maxArrayLength="2147483647" maxBytesPerRead="2147483647"
  maxNameTableCharCount="2147483647" />
  <security mode="None">
  </security>
 </binding>
 </netTcpBinding>

Я отправляю сообщение на сервер, который, как я знаю, отключен, поэтому соединение должно просто отключиться через 3 секунды, как указано в моем app.config, но по какой-то причине оно занимает 20-30 секунд.

Когда вызывается EndPointNotFoundException, это информация, которую я получаю:

System.ServiceModel.EndPointNotFoundException: Не удалось подключиться к net.tcp://10.0.0.82: 4466/MegaMatcherWcf. Попытка подключения продолжалась промежуток времени 00:00:03. Код ошибки TCP 10060: попытка подключения не выполнена потому что связанная сторона не должным образом реагировать после периода время или установленное соединение не удалось потому что подключенный хост не смог ответ 10.0.0.82:4466

Если я попробую один и тот же тест с включенной машиной, но не работает программное обеспечение для прослушивания, я получаю ожидаемое поведение, а время подключения - через 3 секунды. Почему, если машина выключена, это занимает 30 секунд, а затем скажите, что потребовалось 3 секунды?

Ответ 1

Я полагаю, что вы имеете дело с проблемой времени ожидания Windows, а не с таймаутом WCF. Для определения того, что компьютер не отвечает в сети, Windows займет 20-30 секунд. Когда вы делаете свой вызов на сервере WCF, Windows сначала должна установить маршрут к серверу. Когда он не может, он предупреждает ваше программное обеспечение, и ваше программное обеспечение думает, что оно достигло своего таймаута. Ваша система никогда не доходит до фактического опроса, чтобы узнать, работает ли служба, поскольку Windows все еще пытается найти что-то на другом конце этого IP-адреса.

Ответ 2

Чтобы быть более конкретным, чем @BiggsTRC (чей ответ в целом прав):

  • WCF делегирует классам System.Net.Sockets детали установление соединения транспортного уровня в канал NetTcpBinding;
  • System.Net.Sockets - обертка вокруг неуправляемого API WINSOCK;
  • API WINSOCK имеет встроенные таймауты по умолчанию, но не предоставляет документального механизма для указания таймаута для определенных операций блокировки, включая WSAConnect(), который использует метод .NET Socket.Connect();
  • Код WCF (в System.ServiceModel.Channels.SocketConnectionInitiator.Connect()) вызывает Socket.Connect, и если это выдает исключение определенных типов, он проверяет, есть ли оставшееся время в периоде ожидания соединения. Если этого не произошло, вы получите EndpointNotFoundException сообщение об ошибке, которое вы видели;
  • WCF использует класс TimeoutHelper для отслеживания периодов тайм-аута и выполнения арифметики времени. У этого метода есть метод ElapsedTime, но это неправильное словосочетание, поскольку оно никогда не возвращает значение, большее, чем исходный период таймаута. Вот почему вам сообщается сообщение о том, как долго длилась попытка подключения.

WCF может применять свои настроенные таймауты, используя асинхронные методы Sockets API, отслеживая тайм-аут отдельного потока для попытки подключения, но в настоящее время он этого не делает. Если вы считаете, что это ошибка (возможно, это так), вы можете сообщить об этом на сайте Microsoft Connect и, возможно, исправить ее в будущей версии или пакете обновления.

Ответ 3

Столкнулся с той же проблемой

После сохранения сохраненного моего дня

Теперь он не говорил тайм-аут до 5 минут

Сторона сервера

<system.serviceModel>
<diagnostics>
  <messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
  <netTcpBinding>
    <binding name="meritBasicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
             closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00">
      <readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
      <reliableSession ordered="true" inactivityTimeout="00:05:00" enabled="false"/>
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<services>
  <service name="Merit.Services.Reporting" behaviorConfiguration="mexBehaviour">
    <endpoint address="Reporting" binding="netTcpBinding" behaviorConfiguration="meritEndPointBehaviour" bindingConfiguration="meritBasicBinding" contract="Merit.Services.IReporting"></endpoint>        
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"></endpoint>
    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://Localhost:8090/"/>
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="mexBehaviour">
      <serviceMetadata httpGetEnabled="false"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="meritEndPointBehaviour">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </endpointBehaviors>
</behaviors>

Клиентская сторона

<system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="meritBasicBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" listenBacklog="2147483647"
             closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00">
      <readerQuotas maxDepth="128" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
      <security mode="Transport">
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<client>
  <endpoint address="net.tcp://Localhost:8090/Reporting" binding="netTcpBinding"
    bindingConfiguration="meritBasicBinding" behaviorConfiguration="meritEndPointBehaviour" contract="MeritReportingService.IReporting"
    name="NetTcpBinding_IReporting">
    <identity>
      <servicePrincipalName value="host/SERVER DOMAIN ADDRESS(usually picked automatically)" />
    </identity>
  </endpoint>
</client>
<behaviors>
  <endpointBehaviors>
    <behavior name="meritEndPointBehaviour">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </endpointBehaviors>
</behaviors>