WCF Streaming:仅在net.tcp中出现帧模式错误

时间:2013-12-27 20:09:25

标签: c# wcf .net-4.0 stream nettcpbinding

我有一个应用服务器使用默认transferMode="Buffered"和一个Streamed服务实现一堆服务。它公开了basicHttpnet.tcp协议的端点,并在几十个IIS 7.0+配置下运行,无事故。

当我为新应用程序的服务器复制架构时,通过net.tcp流式传输只是拒绝工作,抛出完全不透明和钝的ProtocolException

  

MyNetTcpEndpointAddress 不支持正在使用的.Net帧模式。有关更多详细信息,请参阅服务器日志。

是的,“服务器日志”。 (没有任何内容,无论是否跟踪。)S1和S2的服务架构和web.config是相同的,除了

  • 一些名称更改
  • S2中的自定义命名空间(S1使用tempuri)
  • 不同的端口(S1和S2均使用8000-9000范围内的端口)

流媒体服务S2在basicHttp下工作正常。

尝试了所有内容并且未能使错误消失后,我构建了一个测试客户端,除了使用一些Ping方法运行我的服务架构之外什么都不做。没有自定义命名空间,没有多余的装饰,只有原始配置,精简服务,合同和围绕ChannelFactory代理的手工编码包装。

同样的错误:

  

'net.tcp:// localhost:9931 / StreamingService.svc'不支持正在使用的.Net框架模式。有关更多详细信息,请参阅服务器日志。

缓冲测试服务在两种协议下工作,流式服务在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站点上失败,在两个协议之一,而不是另一个? (它不是this。)

编辑:为了准备接受这个赏金方面,对这个测试服务和客户做了几点澄清:

首先,根据评论者的建议,svcutil对http工作正常,但对net.tcp失败。以下是该运行的完整输出:

  

C:\ Program Files(x86)\ Microsoft SDKs \ Windows \ v7.0A \ Bin&gt; svcutil   net.tcp:// localhost:9931 / StreamingService.svc Microsoft(R)Service   模型元数据工具[Microsoft(R)Windows(R)Communication   基金会,版本3.0.4506.2152]版权所有(c)Microsoft   公司。保留所有权利。

     

尝试从中下载元数据   'net.tcp:// localhost:9931 / StreamingService.svc'使用WS-Metadata   交换。 UR L不支持DISCO。 Microsoft(R)服务   模型元数据工具[Microsoft(R)Windows(R)Communication   基金会,版本3.0.4506.2152]版权所有(c)Microsoft   公司。保留所有权利。

     

错误:无法从中获取元数据   的net.tcp://本地主机:9931 / StreamingService.svc

     

如果这是您的Windows(R)Communication Foundation服务   有权访问,请检查您是否启用了madata数据发布   在指定的地址。有关启用元数据发布的帮助   请参阅MSDN文档   http://go.microsoft.com/fwlink/?LinkId=65455

     

WS-Metadata Exchange错误   URI:net.tcp:// localhost:9931 / StreamingService.svc

     

元数据包含无法解析的引用:'net.tcp:// localhost:9931 / StreamingService.svc'。

     

套接字连接已中止。这可能是由于处理您的消息时出错或超出接收超时造成的   远程主机或底层网络资源问题。本地套接字   超时为'00:04:59.9929993'。

     

远程主机强行关闭现有连接

     

如果您需要更多帮助,请输入“svcutil /?”

其次,从上面粘贴的"transferMode="Streamed"网络和应用配置中移除Wcf.Bindings.Streaming.Tcp,可以让服务ping得很好。它并没有改善svcutil的情况。

最后,我尝试过其他一些事情,没有任何改进:

  • serviceMetadataserviceBehaviors属性的各种版本(我知道无论如何都会被mex端点的覆盖所覆盖)
  • 各种名为serviceBehaviors而不是默认的I
  • 绑定上security mode=的各种配置,尤其是None
  • 所有其他绑定,终点等的各种异议,希望有一件事可能会以另一种方式进入

1 个答案:

答案 0 :(得分:1)

似乎在服务端或客户端传输tcp通信的transferMode到Streamed,而另一端仍然使用默认模式Buffered。

在TCP情况下,您是否忘记了“StreamingProxy”中的内容?

可能会有所帮助...... 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

此外,我正在努力寻找您的解决方案......