voir aussi "WCF de pousser le client à travers pare-feu"
J'ai besoin d'avoir un WCF client de se connecter à un serveur WCF, puis, lorsque certaines des données les modifications sur le serveur, les clients ont besoin de mettre à jour son affichage.
Comme il est susceptible d'être un pare-feu entre les clients et le serveur.
- Toutes les communications doivent être plus HTTP
- Le serveur ne peut pas faire un (physique) appel sortant vers le client.
Comme je l'ai écris à la fois le client et le serveur je n'ai pas besoin de limiter la solution à l'utilisation de savon etc.
Je suis à la recherche d'construit en supporte pour "long polling" / "Comète", etc
Merci pour la plus instructive réponse de Drew Marais sur la façon de mettre en œuvre le long du scrutin dans WCF. Cependant j'ai pensé que le principal "point de vente" de la WCF est qu'on pouvait faire ce genre de chose simplement par la configuration des canaux à utiliser dans le fichier de configuration. E. g je veux un canal qui, logiquement les deux sens, mais physiquement entrants uniquement.
Réponses
Trop de publicités?Il me semble que vous connaissez déjà la réponse: l'utilisation d'interrogation. :) Donc je suppose que la seule chose qui reste à expliquer, c'est comment vous pourriez être en mesure d'accomplir ceci avec WCF et dans la manière la plus efficace possible.
Les principes de base:
- Tout d'abord, décidez combien de temps vous voulez que chaque "long sondage" de l'être. Pour la commodité du raisonnement, je vais choisir 5min délais d'attente.
- Sur le côté client de liaison, de modifier l'
sendTimeout="00:05:00"
. - Tout comme l'utilisation de XmlHttpRequest (XHR) pour le temps d'interrogation, lorsque le délai d'attente ne se produisent réellement, vous aurez besoin de détecter et de re-délivrance de la prochaine requête d'interrogation. C'est assez facile dans WCF, car il y a une exception spécifique,
TimeoutException
, que vous pouvez attraper de détecter facilement ce fut la question contre certains autres d'exception. - Selon la façon dont vous organisez votre service WCF, vous devrez assurez-vous de configurer vous-même pour permettre le traitement jusqu'à 5 minutes. D'un pur point de vue de la WCF, vous voudrez vous assurer que vous définissez l'
receiveTimeout="00:05:00"
. Toutefois, si vous êtes d'hébergement à l'intérieur de ASP.NET vous devrez également configurer l'ASP.NET d'exécution à avoir un plus grand délai d'attente qui est fait à l'aide de l'<httpRuntime executionTimeout="300" />
(note: les mesures sont en secondes pour cet attribut).
Être efficace dans le client
Si vous venez de configurer votre client de façon synchrone appeler le service et le client blocs de 5 minutes en attente d'une réponse, ce n'est pas une utilisation très efficace des ressources du système. Vous pouvez placer ces appels sur les threads d'arrière-plan, mais qui est toujours d'aller à mâcher un fil de ressources alors que l'appel est en suspens. Le moyen le plus efficace de traiter cette question est d'utiliser des opérations asynchrones.
Si vous êtes à la création de vos contrats de service par la main, je vous suggère de vérifier cela l'article sur MSDN sur OperationContractAttribute.AsyncPattern
pour plus de détails sur la façon d'ajouter un BeginXXX
/EndXXX
méthode async paire pour chacun de vos appels. Toutefois, si vous utilisez svcutil
à la création de votre contrat pour vous, tout ce que vous devez faire pour avoir des méthodes asynchrones généré est de passer la /async
option sur la ligne de commande. Pour plus de détails sur ce sujet, consultez le Synchrone et Asynchrone de la rubrique sur MSDN.
Maintenant que vous avez passez vos opérations asynchrones définir, le modèle est très semblable à travailler avec XHR. Vous appelez l' BeginXXX
méthode pour lequel vous passez un AsyncCallback
délégué. L' BeginXXX
méthode va vous renvoyer un IAsyncResult
, que vous pouvez soit accrocher si vous voulez être en mesure d'attendre de l'opération (dans des scénarios plus avancés) ou de l'ignorer, et puis la WCF infrastructure de manière asynchrone d'envoyer la requête au serveur et d'attendre une réponse dans les coulisses. Lors de la réception d'une réponse ou d' une exception se produit, la fonction de rappel que vous avez passé dans l' BeginXXX
méthode sera invoquée. À l'intérieur de cette méthode de rappel, vous devez appeler le correspondant EndXXX
méthode de passage dans l' IAsyncResult
qui est remis à vous. Lors de l'appel à l' EndXXX
méthode vous avez besoin d'employer la gestion des exceptions pour s'occuper de tout type de panne logique qui pourrait avoir eu lieu alors que l'appel de la méthode, mais c'est aussi là que vous avez maintenant être capable d'attraper l' TimeoutException
nous avons parlé plus tôt. En supposant que vous avez une bonne réponse, les données seront retournés à partir de l' EndXXX
appel et vous pouvez réagir à ces données de quelque manière que ce soit, fait sens.
REMARQUE: Une chose à garder à l'esprit à propos de ce modèle est la nature de l'enfilage. L'async des rappels à partir de la WCF va être reçue sur un thread du pool de threads managé. Si vous avez l'intention sur la mise à jour de l'INTERFACE utilisateur dans une technologie telle que WPF ou WinForms, vous devez assurez-vous de rassembler les appels vers le thread d'INTERFACE utilisateur à l'aide de l' Invoke
ou BeginInvoke
méthodes.
Être efficace sur le serveur
Si nous allons être inquiet au sujet de l'efficacité dans le client, nous devrions être doublement quand il s'agit du serveur. Évidemment, ce type d'approche, qui met plus de demande sur le côté serveur car un connexion doit rester ouvert et en attente jusqu'à ce qu'il y a une raison pour envoyer une notification au client. Le défi ici est que vous voulez seulement de la cravate de la WCF d'exécution avec le traitement de ces clients, qui sont en fait envoyé un événement. Tout le reste doit juste être endormi, attendant l'événement de se produire. Heureusement, le même modèle asynchrone nous avons juste utilisé sur le côté client fonctionne aussi sur les serveurs secondaires. Cependant, il y a maintenant une différence majeure: maintenant, vous devez retourner l' IAsyncResult
(et donc un WaitHandle
) de l' BeginXXX
méthode de la WCF runtime, puis d'attendre pour être signalé sur avant d'appeler votre EndXXX
méthode.
Vous allez pas trouver beaucoup de documentation à l'intérieur de MSDN autres que les liens que j'ai déjà fourni plus tôt et, malheureusement, leurs échantillons sur la rédaction d'un asynchrone-service sont moins utiles. Cela dit, Wenlong Dong a écrit une pièce sur l'extension des services WCF avec async modèle il y a quelques temps que je vous recommande vivement de vérifier.
Au-delà de cela, j'ai 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 il dépend entièrement de ce type de source de données de vos événements seront à venir de la première place. Fichier I/O? Un message de la file d'attente? Une base de données? Certains autres logiciels propriétaires avec son propre service de messagerie que vous êtes en essayant de fournir une façade de plus? Je ne sais pas, mais ils sont tous dotés d'une async modèles de leur propre sur lequel vous pouvez entrer votre propre service pour la rendre aussi efficace que possible.
Mise À Jour De Prescription
Depuis ce qui semble être une réponse, j'ai pensé que je devrais revenir ici et de fournir une mise à jour étant donné l'évolution récente dans le paysage. À ce point, il est maintenant un .NET-library appelé SignalR qui fournit cette fonctionnalité et est certainement la façon dont je recommande la mise en œuvre de toute communication avec le serveur.
Alors que pas WCF vous pouvez essayer d'utiliser XMPP pour obtenir cette fonctionnalité va. Il y a un article sur InfoQ à ce sujet et d'autres systèmes. Alors que l'article stipule que XMPP ne peut pas être utilisé sur HTTP, vous pouvez lors de l'utilisation de BOSH.
Il y a des .Bibliothèques NET disponible agsXMPP au nom de l'un.
L'entreprise où je travaille est de commencer à l'utiliser pour pousser les notifications de mise à jour à la demande d'actualisation des parties de l'interface utilisateur.
Si le serveur est capable de faire une connexion sortante vers un service de bus vous pourriez implament un type de retour d'appel. De cette façon, le client/serveur n'aurait pas besoin de savoir au sujet de chaque d'autres, tout le se fier service de bus. Voir .NET Service de Bus
Vous voulez regarder dans les WSDualHttpBinding
Le WSDualHttpBinding fournit l' même support pour les protocoles de Service Web comme le WSHttpBinding, mais pour une utilisation avec les contrats duplex. WSDualHttpBinding prend en charge uniquement du SAVON de sécurité et de nécessite de messagerie fiable. Cette liaison nécessite que le client dispose d'un public URI qui fournit un rappel le point de terminaison pour le service. C'est fournis par le ClientBaseAddress. Un la double liaison expose l'adresse IP de le client vers le service. Le client devrait utiliser la sécurité pour s'assurer qu'il se connecte uniquement sur les services qu'il approuve.
Google pour " duplex WCF ". J'ai utilisé cela avec succès en utilisant netTcpBinding (sur tous les continents), mais je ne suis pas sûr de disposer de basicHttpBinding.
Cependant, le serveur doit être rappelé au client. Si le serveur n'est pas autorisé à le faire, l'interrogation peut être votre seule option ...