Соединение принудительно закрыто по 15 секундному запросу - PullRequest
0 голосов
/ 22 июля 2010

У меня есть запрос к моему собственному сервису, который завершается через 15 секунд. Не должно быть проблемой, верно? На самом деле у нас есть таймер на стороне обслуживания, поэтому для его завершения потребуется максимум 15 секунд. Однако клиент видит «соединение было принудительно закрыто» и автоматически (на уровне System.Net - я видел это при включении диагностики) дважды повторяет запрос GET.

Да, кстати, это не-SOAP ситуация (служба REST WCF 4), поэтому в середине нет ни одного из этих SOAP-компонентов. Кроме того, мой клиент - это программа, а не браузер.

Если я уменьшу время до 5 секунд (что я могу сделать искусственно), повторные попытки прекратятся, но я затрудняюсь объяснить, как соединение должно быть разорвано так быстро. Флаг HttpWebRequest.KeepAlive по умолчанию имеет значение true и не изменяется, поэтому соединение должно оставаться открытым.

Время повторных попыток интересно. Они приходят в конце любого тайм-аута, который мы выберем (например, 10, 15 секунд или что-то еще), поэтому клиентская сторона реагирует только после получения первого ответа.

Другое дело: нет признаков проблемы на стороне обслуживания. Он работает просто отлично, но видит удивительную (для меня) пару повторных запросов от клиента.

Я гуглил эту проблему и выдался пустым. Стандарт поддержания активности составляет более 100 секунд AFAIK, поэтому я все еще озадачен, почему клиент ведет себя так, как есть - и поведение находится на уровне System.Net, поэтому я не могу пройти через него.

Любая помощь здесь будет очень цениться!

== Тевя ==

Ответы [ 3 ]

0 голосов
/ 22 июля 2010

Похоже, что аппаратное обеспечение (маршрутизатор, межсетевой экран, балансировщик нагрузки?) Отправляет RST из-за некоторого выбора конфигурации.

0 голосов
/ 22 июля 2010

Я нашел ответ, и он был почти не связан с таймаутом. Скорее проблема связана с использованием настраиваемой сериализации данных ответа. Структуры данных respose имеют некоторые динамически появляющиеся типы и поэтому не могут быть сериализованы обычными механизмами ASP.NET.

Чтобы решить эту проблему, мы создаем объект XmlObjectSerializer и затем передаем его вместе с объектами для сериализации в System.ServiceModel.Channels.Message.CreateMessage(). Здесь две вещи пошли не так, как надо:

  1. В сообщение [как и почему я не буду вдаваться] был добавлен неожиданный тип, который вызвал сбой сериализации и
  2. Оказывается, что метод CreateMessage() не сразу сериализует содержимое, но откладывает сериализацию до некоторого времени позже (возможно, как раз вовремя).

Два факта вместе вызвали неуловимый сбой сериализации на стороне сервера, потому что фактическая попытка сериализации объектов не происходила, пока написанный пользователем код службы не вернул управление инфраструктуре WCF.

Теперь, почему это выглядело как тайм-аут? Что ж, получается, что не все возвращаемые объекты имели неожиданный тип объекта. В частности, первых N объектов не было. Таким образом, когда срок был увеличен более чем на 5 секунд, N + 1-й объект действительно ссылался на неизвестный тип и был включен в загрузку, которая прервала сериализацию. Последующее тестирование подтвердило, что сбой может произойти, даже если возвращался только один объект.

Решением было предварительно обработать объекты, чтобы не было ссылок на непредвиденные типы. Тогда все идет хорошо.

== Тевя ==

0 голосов
/ 22 июля 2010

Измените службу, чтобы она отправляла клиенту индикацию тайм-аута перед закрытием соединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...