【问题标题】:WCF netTcpBinding issue: Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support itWCF netTcpBinding 问题:合同需要双工,但绑定“BasicHttpBinding”不支持它或未正确配置以支持它
【发布时间】:2016-09-09 14:14:46
【问题描述】:

我正在尝试在 WCF 服务中创建回调。到目前为止服务使用的是 basicHttpBinding,所以我想为 netTcpBinding 添加另一个端点。服务已托管在 IIS 中。首先它托管在 IIS 6 中,然后我安装了 IIS 7。

所以,我收到以下错误:

无法激活请求的服务“net.tcp://localhost:1801/MyServiceName.svc/NetTcpExampleAddress”。有关详细信息,请参阅服务器的诊断跟踪日志。

当看到日志时,这是消息:

所以主要的错误是:

合同需要 Duplex,但绑定“BasicHttpBinding”不支持或未正确配置以支持它。

这是我的配置文件:

我的服务器Web.config:

<system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="demoServiceNetTcpBinding">
          <security mode="None"/>
        </binding>
      </netTcpBinding>
      <basicHttpBinding>
        <binding name="demoServiceHttpBinding" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxReceivedMessageSize="2147483647">
          <security mode="None"/>
        </binding>        
      </basicHttpBinding>
    </bindings>
    <services>
      <service name="MyServerName.MyServiceName">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:1801/MyServiceName.svc/"/>
            <add baseAddress="http://localhost:1800/MyServiceName.svc/"/>
          </baseAddresses> 
        </host>
    <endpoint 
        address="NetTcpExampleAddress" 
        binding="netTcpBinding" 
        bindingConfiguration="demoServiceNetTcpBinding" 
        contract="MyServerName.SharedContract.IMyServiceName"/>
    <endpoint 
        address="BasicHttpExampleAddress" 
        binding="basicHttpBinding" 
        bindingConfiguration="demoServiceHttpBinding" 
        contract="MyServerName.SharedContract.IMyServiceName"/>
    <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

我的客户端App.config:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="demoServiceNetTcpBinding">
          <security mode="None"/>
        </binding>
      </netTcpBinding>
      <basicHttpBinding>
        <binding name="demoServiceHttpBinding" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxReceivedMessageSize="2147483647">
          <security mode="None"/>
        </binding>        
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint name="NetTcpExampleName"
          address="net.tcp://localhost:1801/DicomQueryService.svc/NetTcpExampleAddress"
          bindingConfiguration ="demoServiceNetTcpBinding"
          contract="MyServerName.SharedContract.IMyServiceName"
          binding="netTcpBinding" />
      <endpoint name="BasicHttpExampleName"
          address="http://localhost:1800/MyServiceName.svc/BasicHttpExampleAddress"
          bindingConfiguration ="demoServiceHttpBinding"
          contract="MyServerName.SharedContract.IMyServiceName"
          binding="basicHttpBinding" />
    </client>
  </system.serviceModel>

我的 IIS 中的设置:

如果您需要任何其他代码,请告诉我,我会更新问题。

编辑 1:

以下是代码中的更多详细信息,关于我如何从客户端(在客户端)调用服务:

public class MyCommandClass : IMyServiceCallback
{
    public MyCommandClass()
    {
        var ctx = new InstanceContext(new MyCommandClass());
        DuplexChannelFactory<MyServerName.SharedContract.IMyServiceName> channel = new DuplexChannelFactory<MyServerName.SharedContract.IMyServiceName>(ctx, "NetTcpExampleName");
        MyServerName.SharedContract.IMyServiceName clientProxy = channel.CreateChannel();
        clientProxy.MyFunction(); //debug point is comming here and then it throws the error
        clientProxy.ProcessReport();
        (clientProxy as IClientChannel).Close();
        channel.Close();
    }

    public void Progress(int percentageCompleted)
    {
        Console.WriteLine(percentageCompleted.ToString() + " % completed");
    }
}

接口(在服务器端)定义为:

[ServiceContract(CallbackContract = typeof(IMyServiceCallback))]
public interface IMyServiceName
{
    [OperationContract]
    void MyFunction();

    [OperationContract(IsOneWay = true)]
    void ProcessReport();
}

public interface IMyServiceCallback
{
    [OperationContract(IsOneWay = true)]
    void Progress(int percentageCompleted);    
}

服务(在服务器端)定义为:

public class MyServiceName: IMyServiceName
{
    public void MyFunction()
    {
        //do something
    }

    public void ProcessReport()
    {
        //trigger the callback method
        for (int i = 1; i <= 100; i++)
        {
            Thread.Sleep(100);
            OperationContext.Current.GetCallbackChannel<IMyServiceCallback>().Progress(i);
        }
    }
}

到目前为止,我的方法只是一个演示。一旦与此问题相关的错误得到解决,那么我将开始开发这些方法。

【问题讨论】:

  • demoQueryServiceHttpBinding 应该是 demoServiceHttpBinding 吗?
  • 您能发布一下您是如何从客户端调用服务的吗?
  • @jcmcbeth 我已将 demoQueryServiceHttpBinding 重命名为 demoServiceHttpBinding。这只是我写问题时的语法错误。主要问题仍然存在。此外,我还使用与调用服务的方式相关的更多代码(在编辑 1 中)更新了问题。

标签: wcf wcf-binding nettcpbinding wcf-callbacks duplex-channel


【解决方案1】:

您的服务合同需要双工连接(您有ServiceCallback 属性)。因此,该服务公开的所有端点都必须支持双工连接。 Net.tcp 确实支持它,但 basicHttp 不支持,所以你现在不能在你的服务中使用 basicHttp。

【讨论】:

  • 我在 Web.config 中做了一些更改:我删除了端点“BasicHttpExampleAddress”,这解决了我的问题。此外,我已将“mex”端点重命名为“mextcp”。所以这暂时解决了我的问题,但是如果我想在这里也有“basicHttpBining”怎么办。是否可以同时有不同的端点:“basicHttpBining”(无回调)和“netTcpBinding”(有回调)?
  • 您将不得不使用两个不同的合约。因为合约定义了客户端可以执行的操作。如果合约说它有一个回调,那么无论它如何连接到服务,客户端都应该能够使用回调。如果您的服务还有另一种运行方式(即没有回调),那么再定义一个不使用ServiceCallbackAttribute 的合约并实现另一个服务类。然后您将能够通过 basicHttp 端点公开它。您的两个服务仍然可以在内部使用相同的“后端”进行操作。
猜你喜欢
  • 2011-08-25
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
相关资源
最近更新 更多