2010-07-29 64 views
0

我的目标是在没有传入端口打开的情况下到达防火墙后面的WCF服务。 我选择的解决方案是在公共方面托管一个双工WCF服务,该服务具有与未涉及防火墙时所使用的相同合同的回调。双工WCF服务 - 直接呼叫和回叫不使用相同的通道

它工作,如果我使用netTcpBinding但由于我需要流式通信,我不得不使用自定义绑定。

一切工作正常,直到我举起防火墙。此时,直接调用(从防火墙后面出来)工作正常,但回调不(防火墙停止)。

问题是为什么?他们是否使用与预定义的netTcpBinding相同的通道?

这里是我的渠道的app.config栈:

<customBinding> 
    <binding name="ReversedServiceBinding"> 
    <compositeDuplex /> 
    <oneWay /> 
    <binaryMessageEncoding /> 
    <tcpTransport transferMode="Streamed" /> 
    </binding> 
</customBinding> 
+0

我已经找到了解决方法,以达到我的目标。我没有发布这个答案,因为它实际上并不是我的问题的答案。 如果你需要通过TCP进行双工流式传输,你可以使用这个解决方案:http://msdn.microsoft.com/en-us/library/aa717050.aspx – Gicanu 2010-08-10 09:13:47

回答

2

实际行为是正确的。您已使用compositeDuplex绑定元素 - 复合词的含义正是您所获得的 - 两个单独的通道,每个通道都可以在一个方向上工作。复合双工仅适用于默认不支持双工通信的传输信道。 TCP传输通道并非如此 - 请检查remarks。如果你不使用compositeDuplex,它应该像你预期的那样工作。此外,不需要定义全新的自定义绑定以允许流式传输。 NetTcpBinding也具有可在配置中指定的TransportMode属性。

编辑: 我已经准备好与Net.TCP双工通信的工作示例。它不使用流媒体。如果使用双工TCP通信,则说明传输不可行。您可以尝试将双工通信与分块通道组合在一起,或者检查WCF Xtensions(商业产品)。

共享收缩

namespace NetTcpDuplexContracts 
{ 
    [ServiceContract(SessionMode = SessionMode.Required, 
     CallbackContract = typeof(IDuplexServiceCallback))] 
    public interface IDuplexService 
    { 
     [OperationContract(IsOneWay = true)] 
     void DoAction(string message); 
    } 

    public interface IDuplexServiceCallback 
    { 
     [OperationContract(IsOneWay = true)] 
     void ConfirmAction(string message); 
    } 
} 

服务和主机

namespace NetTcpDuplexService 
{ 
    public class DuplexService : IDuplexService 
    { 
     public void DoAction(string message) 
     { 
      Console.WriteLine("DoAction: " + message); 

      var callbackChannel = 
       OperationContext.Current.GetCallbackChannel<IDuplexServiceCallback>(); 
      callbackChannel.ConfirmAction("Ping back " + message); 
     } 
    } 

    class Program 
    { 
     public static void Main(string[] args) 
     { 
      try 
      { 
       using (var host = new ServiceHost(typeof(DuplexService))) 
       { 
        host.Open(); 

        Console.ReadLine(); 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine(e.Message); 
       Console.ReadLine(); 
      } 
     } 
    } 
} 

服务配置

<configuration> 
    <system.serviceModel> 
    <services> 
     <service name="NetTcpDuplexService.DuplexService"> 
     <host> 
      <baseAddresses> 
      <add baseAddress="net.tcp://localhost:8800/NetTcpDuplexService"/> 
      </baseAddresses> 
     </host> 
     <endpoint address="" binding="netTcpBinding" contract="NetTcpDuplexContracts.IDuplexService" /> 
     </service> 
    </services> 
    </system.serviceModel> 
</configuration> 

回调和客户

namespace NetTcpDuplexClient 
{ 
    public class DuplexServiceCallback : IDuplexServiceCallback 
    { 
     public void ConfirmAction(string message) 
     { 
      Console.WriteLine(message); 
     } 
    } 

    class Program 
    { 
     public static void Main(string[] args) 
     { 
      DuplexChannelFactory<IDuplexService> factory = null; 

      try 
      { 
       var callbackService = new DuplexServiceCallback(); 
       var context = new InstanceContext(callbackService); 

       factory = new DuplexChannelFactory<IDuplexService>(context, "IDuplexService_NetTcp"); 
       var channel = factory.CreateChannel(); 
       channel.DoAction("Hello world"); 

       factory.Close(); 
       Console.ReadLine(); 
      } 
      catch (Exception e) 
      { 
       if (factory != null && factory.State != CommunicationState.Closed) 
       { 
        factory.Abort(); 
       } 

       Console.WriteLine(e.Message); 
       Console.ReadLine(); 
      } 
     } 
    } 
} 

客户CONFIGRATION

<configuration> 
    <system.serviceModel> 
    <client> 
     <endpoint name="IDuplexService_NetTcp" address="net.tcp://localhost:8800/NetTcpDuplexService" binding="netTcpBinding" 
       contract="NetTcpDuplexContracts.IDuplexService" /> 
    </client> 
    </system.serviceModel> 
</configuration> 
+0

在你提供的链接上,MSDN的人说这个元素应该仅适用于本地不支持双工通信的传输协议,这意味着将创建两个通道,每个通信方向一个通道。另一方面,如果我没有在通道堆栈中指定节点,我将无法托管一个双工服务(我收到一个异常说明通道堆栈配置错误,无法进行双工通信)。 所以,我不认为使用两个通道而不是一个通道的原因是因为我已经指定了。 – Gicanu 2010-08-10 09:07:00

+0

如果您可以提供确切的通道堆栈,该通道堆栈适用于不通过节点的TCP传输双工通信,那将证明您是100%正确的,并且您的帖子将成为答案。 无论如何,如果没有人带来其他任何东西,我会将你的帖子标记为答案。 – Gicanu 2010-08-10 09:07:36

+0

关于您的文章中的最后一句,netTcpBinding上的默认双工通信仅适用于缓冲传输模式。 – Gicanu 2010-08-10 09:10:29