我有一个应用程序服务器使用默认 transferMode="Buffered"
和一个 Streamed
服务实现一堆服务。它为 basicHttp
和 net.tcp
协议(protocol)公开端点,并在数十种 IIS 7.0+ 配置下正常运行。
当我去复制新应用程序服务器的架构时,通过 net.tcp 的流式传输根本无法工作,抛出完全不透明和迟钝的 ProtocolException
The .Net Framing mode being used is not supported by MyNetTcpEndpointAddress. See the server logs for more details.
是的,“服务器日志”。 (什么都没有,无论是否被跟踪。)S1 和 S2 的服务架构和 web.configs 是相同的,除了
- 一些名字的变化
- S2 中的自定义命名空间(S1 使用 tempuri)
- 不同的端口(S1 和 S2 都使用 8000-9000 范围内的端口)
流媒体服务 S2 在 basicHttp
下工作得很好。
在尝试了所有方法但未能消除错误后,我构建了一个测试客户端,它除了使用一些 Ping
方法运行我的服务架构外什么都不做。没有自定义命名空间,没有多余的装饰,只有原始配置、精简版服务、契约(Contract)和围绕 ChannelFactory
代理的手工编码包装器。
同样的错误:
The .Net Framing mode being used is not supported by 'net.tcp://localhost:9931/StreamingService.svc'. See the server logs for more details.
缓冲测试服务在两种协议(protocol)下工作,流式服务在 basicHttp
下工作,与 S2 中一样。
所有测试均在具有完整 IIS 设置的同一台 Win7 机器上完成。测试应用仍然太大,无法在此处发布,但这里是完整的配置和控制台代码
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 站点上失败,在两个协议(protocol)之一下,而不是在另一个上? (它不是 this 。)
编辑:在准备接受这个赏金方面,对这个测试服务和客户端进行一些澄清:
首先,根据评论者的建议,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, Version 3.0.4506.2152] Copyright (c) Microsoft Corporation. All rights reserved.
Attempting to download metadata from 'net.tcp://localhost:9931/StreamingService.svc' using WS-Metadata Exchange. This UR L does not support DISCO. Microsoft (R) Service Model Metadata Tool [Microsoft (R) Windows (R) Communication Foundation, Version 3.0.4506.2152] Copyright (c) Microsoft Corporation. All rights reserved.
Error: Cannot obtain Metadata from net.tcp://localhost:9931/StreamingService.svc
If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled m etadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentat ion at http://go.microsoft.com/fwlink/?LinkId=65455.
WS-Metadata Exchange Error URI: net.tcp://localhost:9931/StreamingService.svc
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:9931/StreamingService.svc'.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout bei ng exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.9929993'.
An existing connection was forcibly closed by the remote host
If you would like more help, type "svcutil /?"
其次,从上面粘贴的 Wcf.Bindings.Streaming.Tcp
web 和应用程序配置中删除 "transferMode="Streamed"
允许服务正常 ping。它不会改善 svcutil 情况。
最后,这是我尝试过的其他一些没有改进的东西:
serviceBehaviors
中的各种版本的serviceMetadata
属性(据我所知无论如何都会被mex
端点的存在覆盖)- 各种命名的
serviceBehaviors
而不是我包含的默认值 - 绑定(bind)上
security mode=
的各种配置,尤其是None
- 对所有其他绑定(bind)、端点等进行各种禁用,希望一件事可能妨碍另一件事
最佳答案
似乎服务端或客户端到 Streamed 的 tcp 通信的 transferMode 和另一端仍然使用默认模式,即 Buffered。
如果是 TCP,您是否忘记了“StreamingProxy”中的某些内容?
此外,我正在尝试进一步寻找您的解决方案...
关于c# - WCF 流 : Framing mode error in net. 仅 tcp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20807142/