Comment un serveur WCF informer un client WCF sur les changements? (Meilleure solution alors simple, interrogation, par exemple la comète ou longue interrogation)

StackOverflow https://stackoverflow.com/questions/1700917

Question

  

voir aussi « WCF pousser au client par le biais    pare-feu "

Je dois avoir un client WCF qui se connectent à un serveur WCF, puis lorsque certaines des données modifications sur le serveur les clients ont besoin de mise à jour son affichage.

Comme il est susceptible d'être un pare-feu entre les clients et le serveur.

  • Toutes les communications doivent être sur HTTP
  • Le serveur ne peut pas faire un (physique) appel sortant au client.

Comme je suis en train d'écrire à la fois le client et le serveur, je ne pas besoin de limiter la solution à n'utiliser du savon etc.


Je cherche construit en surport pour " à long de vote" / « Comet » etc


Merci pour la réponse la plus informative de Drew Marsh sur la façon de mettre en œuvre à long sondages dans WCF. Cependant, je pensais que le principal « point de vente » de WCF est que vous pouvez faire ce genre de chose juste en configurant les canaux à utiliser dans le fichier de configuration. Je veux un par exemple canal logique à double sens, mais seulement physiquement entrant.

Était-ce utile?

La solution

Il me semble que vous connaissez déjà la réponse: utiliser l'interrogation longue. :) Je suppose que la seule chose qui reste à expliquer comment vous pourriez être en mesure d'accomplir ceci avec WCF et de la manière la plus efficace possible.


Les bases:

  1. Tout d'abord, décider combien de temps vous voulez que chaque « long sondage » pour être. Pour l'amour de la discussion, je vais choisir les délais d'attente de 5 minutes.
  2. Sur le côté client de liaison, changer le sendTimeout="00:05:00".
  3. Tout comme l'utilisation de XMLHttpRequest (XHR) pour une longue interrogation, lorsque le délai d'attente ne se produit effectivement, vous aurez besoin de le détecter et réémettre la prochaine demande de vote. Ceci est assez facile à WCF, car il y a une exception, TimeoutException , que vous pouvez attraper facilement détecter ce fut la question par rapport à une autre exception.
  4. Selon la façon dont vous organisez votre service WCF, vous devez vous assurer de vous configurer pour permettre le traitement jusqu'à 5 minutes. Du point de vue pur WCF vous voulez vous assurer que vous définissez la receiveTimeout="00:05:00". Cependant, si vous hébergez à l'intérieur d'ASP.NET vous devrez également configurer le runtime ASP.NET pour avoir un délai d'attente plus élevé qui est fait en utilisant la <httpRuntime executionTimeout="300" /> ( Note: les mesures sont en secondes cet attribut).

Être efficace dans le client

Si vous venez de configurer votre client pour appeler le service de manière synchrone et les blocs clients pour 5 minutes en attendant une réponse, ce n'est pas une utilisation très efficace des ressources du système. Vous pouvez placer ces appels sur les sujets de fond, mais qui va encore à mâcher une ressource de fil alors que l'appel est en cours. La façon la plus efficace pour traiter ce problème est d'utiliser des opérations asynchrones.

Si vous créez vos contrats de service à la main, je vous suggère de vérifier cette section sur MSDN sur OperationContractAttribute.AsyncPattern pour plus de détails sur la façon d'ajouter une paire de méthode async BeginXXX / EndXXX pour chacun de vos appels. Toutefois, si vous utilisez svcutil pour générer vos contrats d'exploitation pour vous, tout ce que vous devez faire pour avoir des méthodes async générées est de passer l'option /async sur la ligne de commande. Pour plus de détails sur ce sujet, vérifier le sujet synchrone et asynchrone sur MSDN .

Maintenant que vous avez vos opérations vont async définir, le modèle est très semblable à travailler avec XHR. Vous appelez la méthode BeginXXX auquel vous passez un délégué de AsyncCallback . La méthode BeginXXX vous renvoie un IAsyncResult , que vous pouvez tenir sur si vous voulez être en mesure d'attendre sur le fonctionnement (dans des scénarios plus avancés) ou d'ignorer, et l'infrastructure WCF de manière asynchrone envoyer la demande au serveur et attendre une réponse dans les coulisses. Lorsqu'une réponse est reçue ou une exception se produit, la fonction de rappel que vous avez passé dans la méthode BeginXXX sera appelée. A l'intérieur de cette méthode de rappel que vous devez appeler la méthode correspondante EndXXX passant dans le IAsyncResult qui vous est remis. Au cours de l'appel à la méthode de EndXXX vous devez utiliser la gestion des exceptions pour faire face à tout type de faute logique qui aurait pu se produire tout en appelant la méthode, mais cela est aussi là que vous souhaitez maintenant être en mesure d'attraper le TimeoutException dont nous avons parlé plus tôt. En supposant que vous avez obtenu une bonne réponse, les données seront les revenus de la EndXXXappelez et vous pouvez réagir à ces données de quelque manière logique.

Remarque: Une chose à garder à l'esprit à propos de ce modèle est la nature du filetage. Les callbacks de WCF async seront reçus sur un fil de le pool de threads géré . Si vous envisagez de mettre à jour l'interface utilisateur dans une technologie telle que WPF ou WinForms, vous devez vous assurer que vous maréchal appels vers le thread d'interface utilisateur en utilisant la Invoke ou BeginInvoke méthodes .

être efficace sur le serveur

Si nous allons être inquiet sur l'efficacité dans le client, nous devrions être doublement en ce qui concerne le serveur. Il est évident que ce type d'approche met plus la demande sur le côté serveur car une connexion doit rester ouverte et dans l'attente jusqu'à ce qu'il y ait une raison d'envoyer une notification au client. Le défi ici est que vous voulez seulement attacher le moteur d'exécution WCF avec le traitement de ces clients qui sont en fait envoyés un événement. Tout le reste doit juste être endormi, en attendant que l'événement se produise. Heureusement, le même modèle async nous avons juste utilisé sur le côté client travaille également sur le côté des serveurs. Cependant, il y a maintenant une différence majeure: maintenant doit retourner le IAsyncResult (et donc un Wenlong Dong a écrit une pièce sur l'extension des services WCF avec le modèle async il y a quelque temps que je vous recommande fortement du départ.

Au-delà de cela, je honnêtement, je ne peux pas donner trop de conseils sur la meilleure façon de mettre en œuvre le modèle asynchrone sur le côté serveur pour vous bcause cela dépend entièrement de ce type de source de données vos événements vont venir d'en premier lieu . E / S de fichier? Une file d'attente de messages? Une base de données? Certains autres logiciels propriétaires avec son propre service de messagerie que vous essayez de fournir une façade sur? Je ne sais pas, mais ils devraient tous offrir un modèle async de leur propre sur lequel vous pouvez ferroutage votre propre service pour le rendre aussi efficace que possible.

Prescription

Mise à jour

Comme cela semble être une réponse populaire, je me suis dit que je devrais revenir ici et de fournir une mise à jour compte tenu des récents changements dans le paysage. À ce stade, il y a maintenant une bibliothèque .NET SignalR qui offre cette fonctionnalité exacte et est sans aucun doute que je recommande mettre en œuvre une telle communication avec le serveur.

Autres conseils

Si le serveur pourrait faire une connexion sortante à un bus de service vous pourriez implament un type de rappel. De cette façon, le client / serveur aurait pas besoin de connaître l'autre du tout, juste le bus de service de confiance. Voir service .NET Bus

Vous voulez regarder dans WSDualHttpBinding

  

Le WSDualHttpBinding fournit la   même en charge les protocoles de services Web   comme WSHttpBinding, mais pour une utilisation avec   contrats duplex. WSDualHttpBinding   prend en charge uniquement la sécurité SOAP et   exige une messagerie fiable. Cette   la liaison exige que le client dispose d'un   URI public qui fournit un rappel   point final pour le service. C'est   fourni par le ClientBaseAddress. UNE   double liaison expose l'adresse IP   le client au service. Le client   devrait utiliser la sécurité pour assurer que   ne se connecte aux services qu'il a confiance.   

Sans WCF, vous pouvez essayer d'utiliser XMPP pour obtenir cette fonctionnalité en cours. Il y a un article sur InfoQ à ce sujet et d'autres systèmes. Bien que l'article stipule que XMPP ne peut pas être utilisé sur HTTP, vous pouvez lorsque vous utilisez BOSH .

Il existe des bibliothèques .NET disponibles agsXMPP pour nommer un.

L'entreprise où je travaille commence à l'utiliser pour les notifications push de mise à jour à une demande pour rafraîchir les parties de l'interface utilisateur.

Google pour « WCF duplex ». Je l'ai utilisé avec succès ce en utilisant netTcpBinding (à travers les continents), mais je ne suis pas sûr sur basicHttpBinding.

Cependant, il nécessite le serveur de rappeler au client. Si le serveur ne peut pas le faire, le scrutin peut être votre seule option ...

Si le serveur ne peut pas appeler le client (et il ne devrait pas en général), vous devriez avoir le client le vote serveur que vous avez spécifié. puisque vous avez fondation WCF déjà en place, il suffit d'ajouter une opération pour cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top