2010-04-29 7 views
3

J'ai un problème avec la solution à choisir .. J'ai un serveur en cours d'exécution ayant un service en cours d'exécution qui peut recevoir des commandes d'un site Web. Plusieurs clients (ordinateurs distants) sont connectés à ce serveur. Je voudrais vraiment utiliser WCF pour toutes les communications, mais je ne suis pas sûr que ce soit possible.WCF - rappel au client (duplex?)

Je ne veux pas configurer tous les paramètres de pare-feu du client dans leurs routeurs, de sorte que les clients doivent se connecter au serveur. Mais lorsqu'une commande est reçue sur le serveur, elle doit être transférée à un client spécifique. Une solution pourrait être de connecter le client en utilisant une liaison duplex, mais il devra en quelque sorte garder la connexion active afin de pouvoir recevoir des données du serveur ... Est-ce une bonne façon de faire cela? ?

Normalement, les temps de connexion sur et probablement pour une bonne raison ...

Quelqu'un at-il aperçu de ce problème.

Thx beaucoup pour tout conseiller :-)

Cordialement Søren Müller

+1

Faites attention à ne pas relâcher les sessions dans une batterie de serveurs, par exemple en redémarrant. –

Répondre

4

Ceci est exactement ce que les liaisons duplex ont été conçus pour. Les deux meilleurs choix que vous avez sont NetTcpBinding ou PollingDuplexBinding.

Le premier utilise un protocole TCP qui peut ne pas convenir à vos clients s'ils ne sont pas sur votre réseau. Cependant, il permet une communication bidirectionnelle sur un socket initié par le client. Le client n'a donc pas besoin d'accepter les connexions entrantes. J'ai récemment utilisé ceci sur un projet et cela fonctionne très bien. C'est aussi très réactif. Lorsque les applications client se ferment, la session sur le serveur se termine immédiatement.

La deuxième option, PollingDuplexBinding, est incluse dans le SDK Silverlight. Il utilise une requête HTTP "longue" initiée par le client. La demande attend les messages qui doivent sortir vers le client et quand ils arrivent, la demande du client retourne. Le client envoie ensuite une nouvelle requête HTTP au serveur. En d'autres termes, le client a toujours une requête HTTP en attente. Cela fonctionne bien sur les pare-feu et devrait être utilisé lorsque vous traitez avec des clients Internet. Cependant, j'ai trouvé que ce n'est pas aussi réactif que NetTcpBinding. J'ai peut-être fait quelque chose de mal, mais il semblait que les tentatives d'envoyer des rappels à des sessions clients abandonnées prenaient un certain temps pour "expirer". Voici un exemple du fichier de configuration de mon récent projet utilisant NetTcpBinding pour la communication duplex. Notez que, mis à part quelques ajustements à la limitation de service, j'utilise à peu près les valeurs par défaut pour cette liaison. Mais there's all kinds of things vous pouvez modifier, comme ReceiveTimeout, InactivityTimeout, etc.

<configuration> 
    <system.serviceModel> 

     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 

     <behaviors> 
      <serviceBehaviors> 
       <behavior name=""> 
        <serviceMetadata httpGetEnabled="true" /> 
        <serviceDebug includeExceptionDetailInFaults="true" /> 
        <serviceThrottling maxConcurrentCalls="65535" 
             maxConcurrentSessions="65535" 
             maxConcurrentInstances="65535" /> 
       </behavior> 
      </serviceBehaviors> 
     </behaviors> 

     <bindings> 
      <netTcpBinding> 
       <binding maxConnections="65535"> 
        <security mode="None" /> 
       </binding> 
      </netTcpBinding> 
     </bindings> 

     <services> 
      <service name="BroadcastService"> 
       <endpoint address="" binding="netTcpBinding" contract="BroadcastService" /> 
      </service> 
     </services> 

    </system.serviceModel> 
</configuration> 

[ServiceContract(CallbackContract = typeof(IBroadcastCallback))] 
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class BroadcastService : IDisposable 
{ 

    [OperationContract(IsInitiating=true)] 
    public long Subscribe(Guid clientID) 
    { 
     // clients call this to initiate the session 
    } 

    [OperationContract(IsOneWay = true)] 
    public void Publish(BroadcastMessage message) 
    { 
     // client calls this to broadcast a message to 
     // all other subscribed clients via callback 
    } 

} 

[ServiceContract(Name = "BroadcastCallback")] 
public interface IBroadcastCallback 
{ 

    [OperationContract(IsOneWay = true, AsyncPattern = true)] 
    IAsyncResult BeginBroadcast(BroadcastMessage Message, AsyncCallback callback, object state); 

    void EndBroadcast(IAsyncResult asyncResult); 

} // interface 
+0

Ahh ça sonne bien ... C'est sur internet et comme il me semble je pense que TCPBinding sonne mieux. Mais pour que le serveur envoie des données au client Async, la connexion doit rester active par le client. Y at-il un paramètre sur la liaison pour faire l'affaire ou avez-vous besoin d'envoyer un "message" de pulsation? au serveur afin de le garder en vie ..? Avez-vous un exemple App.config sur la façon de configurer un bon TCPBinding pour cela ?? Thx .. :-) –

+0

Il existe différents paramètres de délai d'attente sur le NetTcpBinding qui contrôlent combien de temps il restera ouvert sans aucune activité, mais à part cela, il n'y a rien de spécial que vous devez faire pour le garder en vie. J'ai utilisé principalement les valeurs par défaut. Je mettrai à jour ma réponse pour inclure la config pertinente de mon projet récent. – Josh

+0

Je suis aussi dans le même genre de situation et j'utilise déjà la liaison nettcp avec la communication duplex. mais mon problème est quand le nombre de connexion atteint environ 800 clients ne répond plus et lance "L'opération d'ouverture n'a pas terminé dans le délai imparti de 00:01:00 Le temps alloué à cette opération peut avoir été une partie d'un délai plus long. " IE: J'utilise la boucle pour créer une connexion au serveur WCF. Appréciez votre aide concernant ce problème. – Mahesh

0

Je l'ai fait peu de recherche pour sélectionner la meilleure approche pour la communication en duplex. Je suis venu avec des solutions suivantes.

service WCF avec WSDualHttpBinding:
Cette approche est bon si le serveur et client à la fois la même adresse IP publique. Le client et le serveur utilisent http pour communiquer donc pas de restriction de pare-feu. Mais lors de l'initialisation du client de communication duplex doit établir une connexion distincte au serveur afin que le client doit également avoir IP publique.

service WCF avec NetTcpBinding:
Cette approche utilise le protocole TCP pour la communication en duplex et cela est du chemin à parcourir si vous utilisez WCF. Seul inconvénient est le blocage de certains ports TCP de pare-feu. Dans ce cas, vous devez avoir une exception de pare-feu.

WCF NetHttpBinding avec prise Web:
cette utilisation approche protocole http donc pas de restriction pare-feu. Dans cette approche, le client initie une connexion http et, plus tard, une mise à niveau vers une connexion TCP pour la communication duplex. Pour le moment seulement gagner 8 ou gagner 2012 prise en charge du système d'exploitation WCF web socket. Tous les serveurs et les clients sont le vent 8 ou gagner 2013 c'est la voie à suivre.

socket Web en utilisant le framework tiers (signal R, Xsocket.net):
Ce n'est pas un WCF mais vous pouvez mettre en œuvre le service Web de repos ou de fenêtres application de service. Utilisez le protocole http et effectuez ensuite une mise à niveau vers TCP pour la communication duplex.

Questions connexes