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>