2010-07-29 67 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