Я пытаюсь сделать работу веб-сервиса WCF в сети с высокой задержкой/низкой пропускной способностью, и все не так, как планировалось. Служба WCF является резидентным в службе Windows, реализующий этот интерфейс:SecurityNegotiationException в службе WCF/TLS только в сети с высокой задержкой
[OperationContract(Name = "send-file")]
[WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
void SendFile(MyFileInfo myFile);
MyFileInfo объекты содержат файл (в виде массива байт). Файл составляет около 45 кбайт (килобайт).
TLS используется с аутентификацией клиента и сервера (сертификаты одного и того же ЦС, клиентов и сервера из того же домена).
ServicePointManager.SecurityProtocol установлен на SecurityProtocolType.Tls12 как на клиентах, так и на сервере, Expect100Continue присваивается значение true, а KeepAlive программно установлен на true в транспортном элементе привязки.
App.config здесь (так же для клиентов и сервера):
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyHttpsBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" messageEncoding="Text"
hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="104857600" maxReceivedMessageSize="104857600"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="104857600" maxArrayLength="104857600" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None" />
<message clientCredentialType="None" ></message>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service
name="MyService"
behaviorConfiguration="MyHttpsBehavior">
<endpoint binding="wsHttpBinding"
bindingConfiguration="MyHttpsBinding" name="MyEndpoint"
contract="IMyInterface">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyHttpsBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="ChainTrust"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Все отлично работает на стандартной локальной сети (WLAN или Ethernet, MTU всегда установлен в 1248 году), но я получаю ошибки при Я переключаюсь на сеть с сильной задержкой/низкой пропускной способностью:
- 800 мс латентность, входящая и исходящая. Это делает ход 1.6sc и обратно поездка.
- 492 Кбит/с (килобиты, а не байты).
- MTU = 1248
Во-первых, мои настройки таймаута app.conf были установлены на 1 минуту и клиент бросил твердый System.TimeoutException: «Канал запроса истекло время ожидания ответа после 00 : 00: 59.1535069. Увеличьте значение тайм-аута, переданного на вызов, чтобы запросить или увеличить значение SendTimeout в привязке. Время, отведенное для этой операции, возможно, было частью более длительного таймаута. ---> System.TimeoutException: HTTP запрос на «https://myserver:4444/» превысил установленный тайм-аут 00:01:00. Время, отведенное для этой операции, возможно, было частью более длительного таймаута ».
На сервере не допущена ошибка.
Если я делаю математику, файл составляет 45 kb = 46080 b ~> 37 пакетов (фрагмент фрагмента MTU &) => 37 * 1600 (латентность) = минимум 1 минута (плюс TLS, плюс полезная нагрузка плюс ...)
Я изменил настройки времени ожидания на клиентах и сервере до 5 минут, а новое исключение клиента совал: «System.ServiceModel.Security.SecurityNegotiationException: не удалось установить доверительные отношения для SSL/TLS защищенного канала с MyServer органа» : 4444 '"
Клиент и сервер могут быть Windows 8 или Windows 2008 R2, брандмауэры не работают, и если я остановлю симулятор задержки (Clumsy), когда-либо все работает отлично.
Я чувствую проблему с TLS больше, чем WCF, но я не эксперт. Может быть, у вас есть идея по этому вопросу?
Заранее благодарен!
Dj
EDIT Я попробовал сеанс Wireshark (вид клиента) и вот результаты:
2 26.958440 client -> server TCP 66 64972 → 4444 [SYN] Seq=0 Win=8192 Len=0 MSS=1208 WS=256 SACK_PERM=1
3 26.958603 server -> client TCP 66 4444 → 64972 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1
4 28.606141 client -> server TCP 54 64972 → 4444 [ACK] Seq=1 Ack=1 Win=66304 Len=0
5 28.606359 client -> server TCP 276 64972 → 4444 [PSH, ACK] Seq=1 Ack=1 Win=66304 Len=222
6 28.610326 server -> client TCP 1262 4444 → 64972 [ACK] Seq=1 Ack=223 Win=66304 Len=1208
7 28.610328 server -> client TCP 711 4444 → 64972 [PSH, ACK] Seq=1209 Ack=223 Win=66304 Len=657
8 30.277053 client -> server TCP 54 64972 → 4444 [ACK] Seq=223 Ack=1866 Win=61440 Len=0
9 30.277177 client -> server TCP 236 64972 → 4444 [PSH, ACK] Seq=223 Ack=1866 Win=61440 Len=182
10 30.279375 server -> client TCP 161 4444 → 64972 [PSH, ACK] Seq=1866 Ack=405 Win=66048 Len=107
11 31.920922 client -> server TCP 331 64972 → 4444 [PSH, ACK] Seq=405 Ack=1973 Win=61440 Len=277
12 31.921599 server -> client TCP 139 4444 → 64972 [PSH, ACK] Seq=1973 Ack=682 Win=65792 Len=85
13 32.249867 client -> server TCP 1262 64972 → 4444 [ACK] Seq=682 Ack=1973 Win=61440 Len=1208
14 32.250099 client -> server TCP 1262 64972 → 4444 [ACK] Seq=1890 Ack=1973 Win=61440 Len=1208
15 32.250226 server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=3098 Win=66304 Len=0
16 32.250437 client -> server TCP 1262 64972 → 4444 [ACK] Seq=3098 Ack=1973 Win=61440 Len=1208
17 32.250699 client -> server TCP 1262 64972 → 4444 [ACK] Seq=4306 Ack=1973 Win=61440 Len=1208
18 32.250816 server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=5514 Win=66304 Len=0
19 33.623716 client -> server TCP 54 64972 → 4444 [ACK] Seq=5514 Ack=2058 Win=61440 Len=0
... lots of similar packets ...
89 37.189910 client -> server TCP 1262 64972 → 4444 [ACK] Seq=61082 Ack=2058 Win=61440 Len=1208
90 37.190103 client -> server TCP 1262 64972 → 4444 [ACK] Seq=62290 Ack=2058 Win=61440 Len=1208
91 37.190260 server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=63498 Win=53760 Len=0
92 37.190303 client -> server TCP 1262 64972 → 4444 [ACK] Seq=63498 Ack=2058 Win=61440 Len=1208
93 37.190499 client -> server TCP 1262 64972 → 4444 [ACK] Seq=64706 Ack=2058 Win=61440 Len=1208
94 37.190654 server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=65914 Win=51200 Len=0
95 37.190699 client -> server TCP 1262 64972 → 4444 [PSH, ACK] Seq=65914 Ack=2058 Win=61440 Len=1208
96 37.190890 client -> server TCP 865 64972 → 4444 [PSH, ACK] Seq=67122 Ack=2058 Win=61440 Len=811
97 37.191046 server -> client TCP 60 4444 → 64972 [ACK] Seq=2058 Ack=67933 Win=49152 Len=0
98 160.241458 server -> client TCP 60 4444 → 64972 [RST, ACK] Seq=2058 Ack=67933 Win=0 Len=0
98-пакет (RST ACK) появляется в то же самое время, как мой исключение на клиенте. На сервере все еще нет ошибок.
Обновление: если я отключу TLS, все будет хорошо – djezzz