Трассировка WCF. Как я могу получить точную причину закрытия соединения?

В моей службе WCF при попытке переноса больших данных я постоянно получаю сообщение об ошибке: Подключенное соединение было закрыто: соединение было неожиданно закрыто

Я хочу знать, какая конкретная причина вызывает эту ошибку, поэтому я настроил трассировку WCF и могу читать файл trace.svclog.

Проблема в том, что я могу видеть в этом файле много информации о потоке процессов, я могу видеть точное время, когда появляется исключение, но я не вижу точной причины этого. Это связано с MaxReceivedMessageSize или что-то в этом роде.

Разве это так, что traces.svclog не может содержать такую ​​информацию, или я делаю что-то неправильно?

Как можно получить такую ​​информацию?

Отредактировано (добавлено):

С моего сервера app.config:

    <system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="NAVBinding_ICustomer_Service"
                closeTimeout="01:50:00"
                openTimeout="01:50:00" receiveTimeout="01:50:00" sendTimeout="01:50:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                maxReceivedMessageSize="2147483647" messageEncoding="Text"
                textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                    maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <services>
        <service name = "Customer_Service"  behaviorConfiguration="returnFaults">
            <endpoint name="NAVBinding_ICustomer_Service"
               address  = "http://localhost:8000/nav/customer"
               binding  = "basicHttpBinding"
               bindingConfiguration= "NAVBinding_ICustomer_Service"
               contract = "NAVServiceReference.ICustomer_Service"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="returnFaults" >
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceMetadata httpGetEnabled="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
 </system.serviceModel>

Отредактировано (добавлено):

Каков правильный и лучший способ превратить службу WCF из "черного ящика" в легкореализованную службу, которая говорит, почему что-то идет не так, как ожидалось? Какие инструменты, методы, которые вы используете для устранения неполадок службы WCF?

Ответ 1

Игнорируя проблемы с maxRequestLength (на которые ответили другие), Я попробую ответить на ваш оригинальный вопрос о том, как устранить проблему WCF.

Если вы уже используете Service Trace Viewer (я не мог сказать по этому вопросу если вы просто просматривали их вручную) - возможно, что все детали не являются входя в файл.

Когда я хочу получить действительно хардкор, я включаю все параметры ведения журнала для ведение журнала сообщений. (Это создаст несколько больших журналов обслуживания, хотя не оставляйте он включен)

 <system.serviceModel>
  <diagnostics>
   <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="-1" />
  </diagnostics>
 </system.serviceModel>

Если вы не используете Microsoft Trace Viewer, я рекомендую это. Это дает всю информацию, необходимую мне для отслеживания этого сложного рукопожатия сообщений, сообщения размер исключения и т.д. Вот ссылка MSDN, чтобы вы начали http://msdn.microsoft.com/en-us/library/aa751795.aspx

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

Troubleshooting Using the Service Trace Viewer

Если вы ничего не получите в журнале обслуживания вашего сервера, то возможно, что ваши исключения полностью завершены на стороне клиента - теоретически вы можете превысить часть своего клиента (размер сообщения и т.д.), прежде чем какое-либо сообщение действительно достигнет конец веб-службы, но проблемы с клиентами, как правило, легче отслеживать, потому что вы знаете, что вам нужно только беспокоиться об изменении файла конфигурации на стороне клиента (т.е. не из-за какого-либо взаимодействия между настройками клиента и сервера).

Ответ 2

Я провел последние 2 дня, пытаясь найти, почему я получаю "Подключенное соединение было закрыто: соединение было неожиданно закрыто", когда вызов метода возвращался с большим количеством данных против того, когда не так много данных (т.е. он работает нормально с меньшими наборами данных, возвращаемых только).

Мои сообщения об ошибках несколько отличаются (возможно, из-за различий в структуре), но хотели поделиться причиной, которую я нашел. Во-первых, я хотел бы заявить, что, хотя отслеживание и увеличение размеров определенных вещей в файлах конфигурации, приведенных в качестве ответов выше, может быть полезно для отслеживания ошибок WCF, эти вещи не помогли мне определить истинную причину ошибки.

Просто посмотрев на исключение, возникшее и связанное с цепочкой, я мог видеть следующий корень: ошибка: "Существующее соединение было принудительно закрыто удаленным хостом" - это был System.Net.Sockets.SocketException

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

"Подключенное соединение было закрыто: произошла непредвиденная ошибка при получении". - System.Net.WebException, а затем, наконец, что было пойманным сообщением исключения,

"Произошла ошибка при получении ответа HTTP. Это может быть связано с привязкой конечной точки службы, не использующей протокол HTTP. Это также может быть вызвано тем, что сервер HTTP-запроса прерывается (возможно, из-за службы выключение). Для получения более подробной информации см. журналы сервера." - System.ServiceModel.CommunicationException

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

В моем случае моя служба WCF размещена на IIS6, и только когда я связался с нашей институциональной поддержкой, отвечающей за эти серверы, и попросил их заглянуть в журналы системных событий, я сразу увидел ответ - исключение System.OutOfMemoryException!

Моя служба WCF работает в выделенной 200 МБ ОЗУ, и мой метод потребляет больше, чем это. Я посмотрел в своем методе и в итоге нашел блок кода, который должен был находиться вне/ниже блока (цикла), в котором он находился...так, у меня был экспоненциальный тип коллекции, сгенерированный в моем методе.

Надеюсь, это может помочь другим.

Ответ 3

Чтобы ответить на вопрос о том, как создать легко загружаемую службу WCF с ошибкой. Один из способов - свести к минимуму количество потенциальных ошибок, так что у вас есть меньше всего, на что можно обратить внимание при устранении неполадок.

Существует два основных источника ошибок:

  • Ошибка из-за конфигурации
  • Исключение, вызванное службой WCF

Ошибки в конфигурации часто связаны с несоответствием между клиентом и службой. Чтобы избежать этого места, вся конфигурация возможна в BindingConfiguration и копировать и использовать это как на клиенте, так и на сервере. На мой взгляд, на самом деле проблема заключается в том, что вы обновляете сервис web.config, а также вещи, которые также должны быть в конфигурации клиента. Для максимального размера макс или с буферизацией в одном и потоковым в другом.

Ошибки, передаваемые службой, должны быть выбраны как исключение FaultException и определены в контракте как FaultContract.

Для остальных ошибок вам нужно посмотреть файл trace.svclog, как описано в других сообщениях. Вам также необходимо просмотреть журнал событий и журнал IIS, вызовы могут быть заблокированы до того, как они достигнут службы WCF.

Ответ 4

Попробуйте установить свойство maxRequestLength:

<system.web>
    <httpRuntime maxRequestLength="2147483647" />
</system.web>

Ответ 5

Для тех, кто все еще сталкивается с этой проблемой - как обычно, есть пара абсолютно важных вещей, оставшихся вне вышеупомянутого обсуждения, без которых нет надежды найти ответ. Вот то, что заняло у меня 3 часа укоренения в Интернете, чтобы узнать.

Напомним: Во-первых, я получил ужасную ошибку Not Found, используя WCF из службы Silverlight. Нет, это не потому, что служба не найдена. Я смог пройти через метод вызываемого сервиса до конца, включая возврат. Затем клиентская сторона получила исключение в асинхронной концевой части вызова. Никаких объяснений. Это не имеет отношения к привязкам и т.д.

Затем я нашел сообщения форума, подобные этому, о том, как использовать средство просмотра трассировки. Оказывается, у меня уже был настроенный, но у меня не было никакого следа (поэтому я решил, что мой сервис должен быть в порядке, особенно, поскольку я мог проследить). Неправильно, мальчик-бонго. Затем я нашел другое сообщение, в котором малоизвестный факт: если вы настроили прослушиватель трассировки для записи в "C:\logs\mylog", вы должны сначала создать C:\logs вручную. Это не сделает для вас.

Хорошо, теперь я получаю журнал и вывожу его в TraceViewer. После чего я получаю сообщение об ошибке о неиспользуемой строке. Через тридцать минут я нахожу еще одно сообщение, говорящее: "О, все знают, что вы должны сначала закончить свой локальный сервер-сервер, чтобы очистить последнее сообщение. Вы знаете, те, которые на самом деле говорят вам, что пошло не так?

Теперь я добираюсь до реальных ошибок и смотрю на каждую из них: Бросать исключение, RequestContext прервано и Не удалось отправить ответное сообщение через http. Только первое имеет значение. Кроме того, если смотреть на нижнюю панель, это не дало мне никакой полезной информации вообще, кроме как сказать, что произошла ошибка сериализации. Um, "where" было бы хорошо.

В моем конце я неожиданно заметил там небольшую вкладку XML в нижней панели, рядом с вкладкой "Отформатирован". Когда я нажимаю на это, для моего сообщения ThrowingAnException, там есть - ginormous дамп с очень специфическим сообщением, которое привело меня к проблеме:

System.ServiceModel.CommunicationException, System.ServiceModel, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089 При попытке сериализации параметра произошла ошибка: GetTimecardsWithAlertsResult. Сообщение InnerException было "Значение Enum '0" является недопустимым для типа "Timeclock.Web.ShiftManager.AlertType" и не может быть сериализовано. Убедитесь, что требуемые значения перечисления присутствуют и отмечены атрибутом EnumMemberAttribute, если у этого типа есть атрибут DataContractAttribute. '. Дополнительную информацию см. В InnerException.

Проблема заключалась в том, что я не инициализировал член класса, основанный на перечислении, поэтому он был 0, что не являлось одним из моих допустимых значений enum. Очень просто исправить.

И, очевидно, очень просто для Microsoft обнаружить, учитывая, что большой объем информации, которую они успешно скрывали от посторонних глаз в течение 3 часов.

Вот идея Microsoft - как насчет того, что вы просто предлагаете способ поймать эти ошибки и всю важную сторону сервера сообщений исключения? Или позволить им полностью перейти к клиенту Silverlight? Вы знаете, чтобы было легко увидеть, что происходит, поэтому я мог бы исправить эту простую проблему за 3 секунды, которые она заслуживает, вместо 3-х часов я должен обвинить своего клиента в том, что он ничего не полезен?

О, я знаю. Это очень сложно, потому что это асинхронный вызов через http, а средний интернет-интернет делает его больно вашему мозгу. Но угадайте, что? Вы Microsoft. У вас есть неограниченное время и деньги. И вы воздействуете на миллионы людей. Когда вы закручиваетесь с помощью такого типа s ** t, как вы делаете с тысячами сценариев, где вас просто не беспокоит, вы затрагиваете сотни тысяч разработчиков по всей планете.

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

Умножьте мои 3 часа на эту глупую проблему, когда десятки тысяч разработчиков разыгрывают 30-40 эпизодов такого рода дерьма в типичный год, и вы видите, какие катастрофы вы вызываете. Это прекрасно, чтобы сказать "почему нам платят большие деньги", но подумайте о том, какую хорошую работу мы могли бы выполнить в мире, если каждый раз, когда мы поворачиваем, нам не нужно было погружаться в 3-х часовой период * * t-hole, которую вы выкопали для нас?

Microsoft, вы плохо для программирования, плохо для бизнеса и плохо для человечества. Мне все равно, сколько компьютеров запускает ваше программное обеспечение. Вам нужно сделать лучше. Пожалуйста, начните действовать так, как вы понимаете, насколько вы злоупотребляете мирянами трудолюбивых людей в мире, в каждой стране, каждый день. И насколько лучше место, где вы могли бы это сделать, если бы вы просто поступали так, как будто это важно, чтобы все было правильно.

Тим Джонсон

Ответ 6

Вы должны получить конкретное исключение связи на стороне клиента. Я думаю, что это исключение, которое вы описываете, является исключением, которое возникает после попытки повторного использования клиента после его возникновения.

Попробуйте следующее:

  • В наборе конфигурационных файлов на стороне сервера includeExceptionDetailInFaults = "true"
  • Когда вы используете клиентскую сторону, не используйте шаблон использования. Проверьте эту статью.

Я не думаю, что вам нужно отслеживать. Попробуйте выше, и вы сможете увидеть точную коммуникационную ошибку.

О, а BTW - ваш клиент - приложение Silverlight? Если это так, то это немного сложнее... Проверьте эту статью.