WCF Streaming: ошибка режима кадрирования только в net.tcp

У меня есть один сервер приложений, реализующий кучу служб, использующих transferMode="Buffered" по умолчанию и одну Streamed службу. Он предоставляет конечные точки для протоколов basicHttp и net.tcp и без проблем запускается в производственной среде в десятках конфигураций IIS 7.0+.

Когда я пошел реплицировать архитектуру для нового сервера приложения, потоковая передача через net.tcp просто отказалась работать, бросая совершенно непрозрачный и тупой ProtocolException

Используемый режим .Net Framing не поддерживается MyNetTcpEndpointAddress. Смотрите журналы сервера для более подробной информации.

Да уж, "журналы сервера". (Нет ничего, отслеживается или нет.) Архитектура служб и web.configs для S1 и S2 идентичны, за исключением

  • некоторые изменения имени
  • настраиваемое пространство имен в S2 (S1 с использованием tempuri)
  • разные порты (S1 и S2 оба используют порты в диапазоне 8000-9000)

Стриминговый сервис S2 отлично работает под basicHttp.

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

Та же ошибка:

Используемый режим .Net Framing не поддерживается net.tcp: // localhost: 9931 / StreamingService.svc. Смотрите журналы сервера для более подробной информации.

Буферизованный тестовый сервис работает по обоим протоколам, а потоковый сервис работает под basicHttp, как в S2.

Все тесты проводились на одной машине Win7 с полной настройкой IIS. Тестовое приложение все еще слишком велико, чтобы публиковать его здесь, но вот полные конфигурации и код консоли.

web.config

<configuration>
  <connectionStrings>
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <!-- throttling of stream size is partially controlled by this setting -->
    <httpRuntime maxRequestLength="1048576" /><!-- 1GB -->
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment>
      <serviceActivations>
        <add relativeAddress="FooService.svc" service="WcfTest.Services.FooService" />
        <add relativeAddress="StreamingService.svc" service="WcfTest.Services.StreamingService" />
     </serviceActivations>
    </serviceHostingEnvironment>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <dataContractSerializer maxItemsInObjectGraph="200000" />
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding
                 openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
                 maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
          <readerQuotas maxStringContentLength="12000" />
        </binding>
        <binding name="WcfTest.Streaming.Http" transferMode="Streamed"
                 openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
                 maxReceivedMessageSize="1073741824" /><!-- 1GB -->
      </basicHttpBinding>
      <netTcpBinding>
        <binding
                 openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
                 maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
          <readerQuotas maxStringContentLength="12000" />
        </binding>
        <binding name="WcfTest.Streaming.Tcp" transferMode="Streamed"
                 openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
                 maxReceivedMessageSize="1073741824"><!-- 1GB -->
        </binding>
      </netTcpBinding>
    </bindings>
    <protocolMapping>
      <add scheme="http" binding="basicHttpBinding" />
      <add scheme="net.tcp" binding="netTcpBinding"/>
    </protocolMapping>
    <services>
      <service name="WcfTest.Services.Streaming">
        <!-- http -->
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="WcfTest.Streaming.Http" contract="WcfTest.Contracts.IStreamingService" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <!-- net.tcp -->
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="WcfTest.Streaming.Tcp" contract="WcfTest.Contracts.IStreamingService" />
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

app.config

<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior>
          <dataContractSerializer maxItemsInObjectGraph="200000"/>
        </behavior>
        <behavior name="customQuotaBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding
                 openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
                 maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
          <readerQuotas maxStringContentLength="12000" />
        </binding>
        <binding name="WcfTest.Bindings.Streaming.Http" transferMode="Streamed"
                 openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
                 maxReceivedMessageSize="1073741824"><!-- 1GB -->
          </binding>
      </basicHttpBinding>

      <netTcpBinding>
        <binding
                 openTimeout="00:20:00" sendTimeout="00:20:00" receiveTimeout="00:20:00" closeTimeout="00:20:00"
                 maxBufferSize="20000000" maxBufferPoolSize="20000000" maxReceivedMessageSize="20000000">
          <readerQuotas maxStringContentLength="12000" />
        </binding>
        <binding name="WcfTest.Bindings.Streaming.Tcp" transferMode="Streamed"
                 openTimeout="03:00:00" sendTimeout="03:00:00" receiveTimeout="03:00:00" closeTimeout="03:00:00"
                 maxReceivedMessageSize="1073741824"><!-- 1GB -->
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <!-- Foo -->
      <endpoint name="WcfTest.Endpoints.Foo.Http" address="http://localhost:9930/FooService.svc" binding="basicHttpBinding" contract="WcfTest.Contracts.IFooService" />
      <endpoint name="WcfTest.Endpoints.Foo.Tcp" address="net.tcp://localhost:9931/FooService.svc" binding="netTcpBinding" contract="WcfTest.Contracts.IFooService" />

      <!-- Streaming -->
      <endpoint name="WcfTest.Endpoints.Streaming.Http" address="http://localhost:9930/StreamingService.svc" binding="basicHttpBinding" bindingConfiguration="WcfTest.Bindings.Streaming.Http" contract="WcfTest.Contracts.IStreamingService" />
      <endpoint name="WcfTest.Endpoints.Streaming.Tcp" address="net.tcp://localhost:9931/StreamingService.svc" binding="netTcpBinding" bindingConfiguration="WcfTest.Bindings.Streaming.Tcp" contract="WcfTest.Contracts.IStreamingService" />
    </client>
  </system.serviceModel>
</configuration>

тестовый вызов консоли

static void Main(string[] args)
        {
            Console.WriteLine("starting WcfTest client...");

            Console.WriteLine();
            PingFoo(Contracts.Enums.Protocol.Http);
            PingFoo(Contracts.Enums.Protocol.Tcp);

            Console.WriteLine();
            PingStreaming(Contracts.Enums.Protocol.Http);
            // only this call errors:
            PingStreaming(Contracts.Enums.Protocol.Tcp);

            Console.WriteLine();
            Console.Write("ENTER to exit WcfTest client...");
            Console.ReadLine();
        }

        private static bool PingFoo(Contracts.Enums.Protocol protocol)
        {
            FooProxy pxy = new FooProxy(protocol);
            return PingProxy<IFooService>(pxy, protocol);
        }

        private static bool PingStreaming(Contracts.Enums.Protocol protocol)
        {
            StreamingProxy pxy = new StreamingProxy(protocol);
            return PingProxy<IStreamingService>(pxy, protocol);
        }

        private static bool PingProxy<T>(ProxyServiceBase<T> pxy, Contracts.Enums.Protocol protocol) where T : IServiceBase
        {
            bool success = pxy.Ping(); 
            Console.WriteLine("ping {0} {1}: {2}", pxy.GetType().Name, protocol, success ? " success" : " FAILED");
            if (pxy != null)
                pxy.Close();
            return success;
        }

Есть идеи, почему это не работает на одном сайте IIS по одному из двух протоколов, а не на другом? (Это не это.)

РЕДАКТИРОВАТЬ: В рамках подготовки к участию в конкурсе, пара пояснений по этой тестовой службе и клиенту:

Во-первых, согласно предложению комментатора, svcutil отлично работает с http, но не работает с net.tcp. Вот полный результат этого прогона:

C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin> svcutil net.tcp: // localhost: 9931 / StreamingService.svc Инструмент метаданных модели службы Microsoft (R) [Microsoft (R) Windows (R) ) Communication Foundation, версия 3.0.4506.2152] Авторское право (c) Корпорация Microsoft. Все права защищены.

Попытка загрузить метаданные из net.tcp: // localhost: 9931 / StreamingService.svc с помощью WS-Metadata Exchange. Этот UR L не поддерживает DISCO. Средство метаданных модели обслуживания Microsoft (R) [Microsoft (R) Windows (R) Communication Foundation, версия 3.0.4506.2152] Авторское право (c) Microsoft Corporation. Все права защищены.

Ошибка: не удается получить метаданные из net.tcp: // localhost: 9931 / StreamingService.svc

Если это служба Windows (R) Communication Foundation, к которой у вас есть доступ, убедитесь, что вы включили публикацию метаданных по указанному адресу. Чтобы получить помощь по включению публикации метаданных, обратитесь к документации MSDN по адресу http://go.microsoft.com/fwlink/?LinkId=65455.

URI ошибки обмена WS-метаданными: net.tcp: // localhost: 9931 / StreamingService.svc

Метаданные содержат ссылку, которую невозможно разрешить: 'net.tcp: // localhost: 9931 / StreamingService.svc'.

Соединение с сокетом было прервано. Это может быть вызвано ошибкой при обработке вашего сообщения, превышением таймаута приема на удаленном узле или проблемой базового сетевого ресурса. Тайм-аут локального сокета был «00: 04: 59.9929993».

Существующее соединение было принудительно закрыто удаленным хостом

Если вам нужна дополнительная помощь, введите "svcutil /?"

Во-вторых, удаление "transferMode="Streamed" из Wcf.Bindings.Streaming.Tcp сети и вставленных выше конфигураций приложений позволяет службе нормально пинговать. Это не улучшает ситуацию с svcutil.

Наконец, вот еще несколько вещей, которые я пробовал, но без улучшений:

  • Различные версии атрибута serviceMetadata в serviceBehaviors (который, как я понимаю, в любом случае отменяется существованием mex конечных точек)
  • Различное название serviceBehaviors вместо значения по умолчанию, которое я включаю
  • Различные конфигурации security mode= по привязке, особенно None
  • Различные блокировки всех других привязок, конечных точек и т. Д. В надежде, что одно может мешать другому.

person downwitch    schedule 27.12.2013    source источник
comment
Введите код StreamingProxy для проверки.   -  person Jones    schedule 29.12.2013
comment
@Jones В прокси-сервере ничего нет. Открытие канала и вызов Ping происходят в ProxyServiceBase, который, как я уже сказал, идентичен предыдущему сервису, который работал   -  person downwitch    schedule 30.12.2013
comment
Использование svcutil net.tcp://localhost:9931/StreamingService.svc и проверка правильности ответа. Если нет проблем, используйте журнал msdn.microsoft.com/ en-us / library / ms730064 (v = vs.100) .aspx для точки обнаружения ошибки происходит точно   -  person Jones    schedule 30.12.2013
comment
@Jones Извините, что так медленно отвечаю ... Я получаю, что метаданные содержат ссылку, которая не может быть разрешена в ответ от svcutil. Я много искал по этому поводу, но мои конфигурации метаданных в порядке (и, что немаловажно, такие же, как и в предыдущем сервисе / сравнении). Включена трассировка и в журнале нет ошибок.   -  person downwitch    schedule 04.03.2014


Ответы (1)


Кажется, что transferMode tcp-связи либо на стороне службы, либо на стороне клиента для потоковой передачи, а другая сторона по-прежнему использует режим по умолчанию, который является буферизованным.

Вы что-то забываете в "StreamingProxy" в случае TCP?

Может быть, это поможет ... http://social.msdn.microsoft.com/Forums/vstudio/en-US/37e32166-63f3-4cb9-ab81-14caa50cd91e/help-with-error-message-the-net-framing-mode-being-used-is-not-supported-by-?forum=wcf

Также я пытаюсь найти ваше решение ...

person Dharmendra Mistry    schedule 10.03.2014
comment
Конфигурационные файлы клиента (приложения) и сервера (веб) находятся в исходном посте, и оба явно указаны как использующие Streamed. Я не знаю, что Вы что-то забываете в StreamingProxy в случае TCP? означает, что я не устанавливаю свои протоколы в коде. - person downwitch; 11.03.2014
comment
Я хочу сказать, что вы установили binding.TransferMode = TransferMode.Streamed в классе StreamingProxy метода ping, даже если вы установили его в app.config? (Как Джонс также заявил для кода). Пытаясь выяснить, правильно ли настроен wcf, тогда это должен быть клиент, использующий буферизованный режим, поскольку обе конфигурации кажутся нормальными. - person Dharmendra Mistry; 15.03.2014