Ошибка потокового ответа WCF для больших данных - PullRequest
0 голосов
/ 13 июля 2010

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

Объекты - это различные объекты, отправляемые через один поток, большинство из которых небольшие, но в них также есть jpeg, размер которых варьируется от 10 до 500 тысяч на объект. Я не могу примирить разные случаи:

  1. Если мы запустим его по нашей внутренней сети, он будет работать отлично, даже если мы увеличим объем передаваемых данных в 10 раз выше, чем в реальном случае, поэтому мы отправляем гигабайты данных.
  2. Если мы запустим его на серверах, на которых размещено решение, через несколько минут и несколько сотен мегабайт получит ошибку (подробно описано ниже).
  3. Если мы запустим его на серверах, но удалим фотографии (отправка только других данных), это будет успешно выполнено и отправит примерно 40 Мб за более длительный период времени, чем требуется для сбоя (Чем дольше, тем больше времени требуется для обработки других данных так вот и ожидается).
  4. Мы проверили простую загрузку файла 1 ГБ с веб-сервера (это значительно больше, чем любой другой тест, кроме тестов, которые мы пробовали в нашей локальной сети), и он прошел успешно несколько раз без проблем.

Ошибка, которую мы получаем на стороне клиента (Примечание: мы не приблизились к установленному нами 3-часовому таймауту):

System.Reflection.TargetInvocationException: An exception occurred during the operation, making the result invalid. Check InnerException for exception details. ---> 
System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '03:00:00'. ---> 
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> 
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

И на стороне сервера мы видим:

System.ServiceModel.CommunicationException,
System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 The remote host closed the connection. The error code is 0x80070016.

Настройка привязки WCF (с небольшой анонимностью):

  <system.serviceModel>
    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://anonymous"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <bindings>
      <basicHttpBinding>
        <binding name="StreamedHttpBindingConfig" transferMode="StreamedResponse" maxReceivedMessageSize="2147483647" maxBufferSize="8388608" sendTimeout="01:00:00">
          <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"
            maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" maxDepth="2147483647" />
          <security mode="None" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="wsHttpBindingBehaviour" name="AnonymousName">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="StreamedHttpBindingConfig" name="wsHttpBinaryBindingEndpoint" contract="Service.IAnonymous" />
        <endpoint address="mex" binding="mexHttpBinding" name="mexHttpBindingEndpoint" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://anonymous/Service" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wsHttpBindingBehaviour">
          <serviceThrottling maxConcurrentCalls="160" maxConcurrentSessions="100" maxConcurrentInstances="100" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

И договор на обслуживание (имена методов / параметров изменены для анонимности, но вводит то же самое):

System.ServiceModel.Channels.Message GetData(System.ServiceModel.Channels.Message request);

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

Ответы [ 2 ]

0 голосов
/ 18 июня 2014

Я очень долго искал решение и добавил каждую найденную конфигурацию для увеличения объема данных. в конечном итоге мне помогла строка под тегом <behavior> в web.config, которая на стороне сервера:

<dataContractSerializer maxItemsInObjectGraph ="2147483647"/>

и убедитесь, что у меня такое же поведение на стороне клиента.

0 голосов
/ 27 апреля 2012

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

Например:

<behaviors> 
            <serviceBehaviors> 
                <behavior 
                    <serviceMetadata httpGetEnabled="true" /> 
                    <serviceDebug includeExceptionDetailInFaults="true" /> 
                </behavior> 
            </serviceBehaviors> 
        </behaviors> 

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

Как правило, после того, как вы это сделаете, вам нужно будет получить больше информации о том, что происходит на стороне службы, и быстро диагностировать проблему.Попробуйте, и, пожалуйста, сообщите!:)

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