WCF, возможно, превысил мой размер ответа - PullRequest
3 голосов
/ 23 февраля 2012

Хорошо, так что я наконец-то запустил мою службу WCF. Это заняло у меня некоторое время, но я решил почти все свои проблемы. Единственная проблема, с которой я столкнулся сейчас, это эта.

Один из моих запросов данных довольно большой, он содержит коллекцию около 37 КБ. Я получаю следующую ошибку.

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 '00:00:59.9840000'.

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

Вот моя привязка, на клиенте.

<netTcpBinding>
<binding name="MyCustomBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
                receiveTimeout="00:10:00" sendTimeout="00:01:00" 
                transactionFlow="false" transferMode="Buffered" 
                transactionProtocol="OleTransactions" 
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="1000000000" maxBufferSize="1000000000" 
                maxConnections="10" maxReceivedMessageSize="1000000000">
                <readerQuotas maxDepth="32" maxStringContentLength="1000000000" 
                    maxArrayLength="50000" maxBytesPerRead="4096" 
                    maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" 
                               protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
</netTcpBinding>

Я изменил свою обязательную информацию, чтобы увеличить емкость; однако, это не решает мою проблему. Единственная причина, по которой я начал смотреть на изменение емкости для maxReceiveMessageSize, заключается в том, что если я уменьшу результаты до 1000, у меня не будет проблем. Есть ли какие-либо конфигурации, кроме привязки, о которых мне нужно беспокоиться, когда речь идет о больших коммуникациях?

Спасибо!

РЕДАКТИРОВАТЬ 1

Также я изменил свой тайм-аут на значение 00:10:00 для каждого значения тайм-аута в привязке, и это, похоже, не имело значения. Ответ от сервера длится менее 5 секунд.

Редактировать 2

Сервисный конфиг.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<configSections>
</configSections>
<system.web>
   <compilation debug="true" />
</system.web>
<system.serviceModel>
<bindings />
<client />
<services>
  <service behaviorConfiguration="serviceBehavior"                      
           name="MyService">
    <clear />
    <endpoint address="MyCustomObject" binding="netTcpBinding" 
              bindingConfiguration="" name="MyCustomObject" 
              contract="MyService.IContract" >
    </endpoint>

    <host>
      <baseAddresses>
        <add baseAddress="net.tcp://localhost:8732/MyService/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehavior">
      <serviceMetadata />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>

</configuration>

РЕДАКТИРОВАТЬ 3

Пожалуйста, поймите, что я не включил конфиденциальную информацию об этой модели сервиса, поэтому они были заменены на MyCustom ***. Опять же, пожалуйста, внимательно прочитайте вопрос. Я успешно передаю данные туда и обратно, используя этот сервис, через другие конечные точки без проблем. Кроме того, как я уже говорил выше, я могу передавать данные через эту конечную точку, если я ограничу результат до 1000.

РЕДАКТИРОВАТЬ 4

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

The maximum message size quota for incoming messages (65536) has 
been exceeded. To increase the quota, use the MaxReceivedMessageSize 
property on the appropriate binding element.

Поэтому я увеличиваю MaxReceiveMessageSize до максимально возможного значения, 2147483647. Согласно этому посту . После этого я могу безопасно вернуть свой набор результатов. Теперь вот кикер, у меня до 5000 результатов и я получаю свое первоначальное исключение в верхней части этого вопроса.

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 '00:00:59.9840000'.

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

Ответы [ 3 ]

3 голосов
/ 24 февраля 2012

НАКОНЕЦ! Итак, это была проблема. Я превышал значение MaxItemsInObjectGraph на стороне клиента. Поэтому мне нужно было добавить это поведение в файл конфигурации клиентов.

Конфигурация сервера

<behaviors>
  <serviceBehaviors>
    <behavior name="serviceBehavior" >
      <serviceMetadata />
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Конфиг клиента

<behaviors>
<endpointBehaviors>
  <behavior name="endpointBehavior">
    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
  </behavior>
</endpointBehaviors>
</behaviors>

Затем в конечной точке файла конфигурации клиентов мне пришлось добавить это поведение.

Конфигурация клиента

<client>
<endpoint address="net.tcp://localhost:8732/RootAddress/EndpointLocation"
          binding="netTcpBinding" bindingConfiguration="EndpointLocation"
          behaviorConfiguration="endpointBehavior"
          contract="ServiceReference1.IInterface" name="Interface">
   <identity>
     <userPrincipalName value="" />
   </identity>
</endpoint>
</client>

Просто чтобы заметить, мне пришлось полностью добавить секцию поведений в конфигурацию на стороне клиента. Как это не было сгенерировано, когда я использую Add Service Reference. Впоследствии это работало безупречно, и я смог получить свою коллекцию пользовательских объектов размером 37 КБ.

0 голосов
/ 24 февраля 2012

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

Если вы измените атрибут name в элементе service на полное имя, он должен подобрать правильные настройки

0 голосов
/ 24 февраля 2012

Вы используете привязку netTcp на сервере, но клиент настроен с настраиваемой привязкой.

Они должны совпадать, чтобы она работала.

То, что работает вообще, возможно, связано сесли пользовательская привязка очень близка к netTcpbinding.

То, что перестает работать при заданном размере менее 64 КБ, возможно, связано с режимом передачи.Buffered разбивает запрос по блокам, если есть один чанк, который он работает, когда более одного различия в конфигурации приводят к сбою.

...