WCF issues with wsDualHttpBinding and netTcpBindin

2019-04-14 16:52发布

问题:

I have a standalone WCF service running on a server behind a firewall. It currently uses wsDualHttpBinding as the service utilizes callbacks. The client works fine in a LAN environment. We have opened the firewall to allow traffic on a custom port and so the discovery of the service now works from outside LAN.

Due to the nature of wsDualHttpBinding this obviously cannot work if the client is behind a firewall of its own. So naturally, netTcpBinding comes to mind which should solve the bidirectional problem. But the strange thing is that when service configuration XML is updated to include netTcpBinding on the same port (and/or exclude wsDualHttpBinding), then even the service discovery no longer works.

I am wondering if there is anything else that I am missing. I have followed the exact advice for configuration from How to: Use netTcpBinding with Windows Authentication and Message Security in WCF Calling from Windows Forms and from Windows Communication Foundation QuickStart - Multiple Binding VS2010.

The configuration:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingEndpointConfig">
        <security mode="Message" />
      </binding>
    </netTcpBinding>
  </bindings>
  <services>
    <service name="Service1.Service1.Service">
      <endpoint address="Service1" binding="wsDualHttpBinding" contract="Service1.IService1">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      <endpoint address="" binding="netTcpBinding"
                 bindingConfiguration="NetTcpBindingEndpointConfig"
                 name="NetTcpBindingEndpoint" contract="Service1.IService1">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:9999/Service1.Service1/"/>
          <add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <!-- To avoid disclosing metadata information, 
        set the value below to false and remove the metadata endpoint above before deployment -->
        <serviceMetadata httpGetEnabled="True"/>
        <!-- To receive exception details in faults for debugging purposes, 
        set the value below to true.  Set to false before deployment 
        to avoid disclosing exception information -->
        <serviceDebug includeExceptionDetailInFaults="True"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

回答1:

If you can use only single port and you must use netTcpBinding try to configure your service this way:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="NetTcpBindingEndpointConfig">
        <security mode="Message" />
      </binding>
    </netTcpBinding>
  </bindings>
  <services>
    <service name="Service1.Service1.Service">
      <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
      <endpoint address="" binding="netTcpBinding"
                 bindingConfiguration="NetTcpBindingEndpointConfig"
                 name="NetTcpBindingEndpoint" contract="Service1.IService1">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
        </baseAddresses>
      </host>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="False"/>
        <serviceDebug includeExceptionDetailInFaults="True"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

When adding service reference try to use this address:

net.tcp://localhost:9999/Service1.Service1/mex