Имам един сървър за приложения, който прилага куп услуги, използвайки transferMode="Buffered"
по подразбиране и една Streamed
услуга. Той разкрива крайни точки за basicHttp
и net.tcp
протоколи и работи в производство при десетки IIS 7.0+ конфигурации без инциденти.
Когато отидох да репликирам архитектурата за сървър на ново приложение, стриймингът през net.tcp просто отказа да работи, изхвърляйки идеално непрозрачния и тъп ProtocolException
Използваният режим .Net Framing не се поддържа от MyNetTcpEndpointAddress. Вижте регистрационните файлове на сървъра за повече подробности.
Да, правилно, "сървърните регистрационни файлове". (Няма нищо, независимо дали е проследено или не.) Архитектурите на услугите и web.configs за S1 и S2 са идентични, с изключение на
- някои промени в името
- персонализирано пространство от имена в S2 (S1 използва темпури)
- различни портове (и двата 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) Service Model Metadata Tool [Microsoft (R) Windows (R) ) Communication Foundation, версия 3.0.4506.2152] Авторско право (c) Microsoft Corporation. Всички права запазени.
Опит за изтегляне на метаданни от „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.
Грешка при обмен на WS-метаданни URI: 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
- Различни деактивации на всички други свързвания, крайни точки и т.н. с надеждата, че едно нещо може да пречи на друго
StreamingProxy
за проверка. - person Jones   schedule 29.12.2013Ping
повикването се случват вProxyServiceBase
, което, както казах, е идентично с по-ранната услуга, която работи - person downwitch   schedule 30.12.2013svcutil net.tcp://localhost:9931/StreamingService.svc
и проверка дали отговорът е правилен. Ако не е проблем при използване на журнал msdn.microsoft.com/ en-us/library/ms730064(v=vs.100).aspx за точка на откриване на грешката се появява точно - person Jones   schedule 30.12.2013