2010-07-29 28 views
0

Mon but est d'atteindre un service WCF derrière un pare-feu sans ouverture de ports entrants. La solution que j'ai choisie est d'héberger un service WCF duplex sur le côté public, qui a comme rappel le même contrat qui était utilisé si aucun pare-feu n'était impliqué.Service WCF en duplex - L'appel direct et le rappel n'utilisent pas le même canal

Cela a fonctionné si j'ai utilisé netTcpBinding mais comme j'ai besoin d'une communication en streaming, j'ai dû utiliser la liaison personnalisée. Tout fonctionne bien jusqu'à ce que j'élève le pare-feu. À ce moment-là, l'appel direct (derrière le pare-feu) fonctionne bien, mais pas le rappel (le pare-feu l'arrête).

La question est POURQUOI? Ne devraient-ils pas utiliser le même canal que pour le netTcpBinding prédéfini?

Voici mes chaînes pile dans app.config:

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

J'ai trouvé une solution pour atteindre mon objectif. Je n'ai pas affiché cela comme réponse parce que ce n'est pas vraiment la réponse à ma question. Si vous avez besoin d'une communication en mode duplex sur TCP, vous pouvez utiliser cette solution: http://msdn.microsoft.com/en-us/library/aa717050.aspx – Gicanu

Répondre

2

comportement réel est correct. Vous avez utilisé l'élément de liaison compositeDuplex - la signification du mot composite est exactement ce que vous obtenez - deux canaux distincts travaillant chacun dans une direction. Un duplex composite est nécessaire uniquement pour un canal de transport qui ne prend pas en charge la communication duplex par défaut. Ce n'est pas le cas pour le canal de transport TCP - vérifiez remarks. Si vous n'utilisez pas compositeDuplex, cela devrait fonctionner comme prévu. De plus, il n'est pas nécessaire de définir une nouvelle liaison personnalisée pour permettre le transport en continu. NetTcpBinding possède également la propriété TransportMode qui peut être spécifiée dans la configuration.

EDIT: J'ai préparé un exemple de travail avec la communication duplex Net.TCP. Il n'utilise pas le streaming. Vous avez raison de dire que le streaming n'est pas possible lorsque la communication TCP duplex est utilisée. Vous pouvez essayer de combiner la communication duplex avec le canal de partage ou vérifier WCF Xtensions (produit commercial).

partagés contrats

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); 
    } 
} 

Service et hôte

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 de service

<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> 

Callback et client

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(); 
      } 
     } 
    } 
} 

client 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

Au niveau du lien que vous avez fourni, les utilisateurs de MSDN disent que l'élément doit être spécifié uniquement pour les protocoles de transport qui ne supportent pas nativement la communication duplex, ce qui implique que deux canaux seront créés, un pour chaque direction de communication.Par contre, si je ne spécifie pas le noeud dans la pile des canaux, je ne peux pas héberger un service duplex (je reçois une exception disant que la pile des canaux est mal configurée pour la communication duplex). Donc, je ne suis pas convaincu que la raison pour laquelle deux canaux sont utilisés au lieu d'un est parce que j'ai spécifié . – Gicanu

+0

Si vous pouviez fournir la pile de canaux exacte qui fonctionne pour une communication duplex sur un transport TCP sans le noeud , cela prouvera que vous avez 100% raison, et votre message sera la réponse. Je vais quand même marquer votre message comme la réponse, si personne ne vient avec autre chose pendant quelques jours. – Gicanu

+0

Et à propos de la dernière phrase de votre publication, la communication duplex par défaut sur netTcpBinding ne fonctionne que pour le mode de transport mis en mémoire tampon. – Gicanu