2008-10-15 12 views
13

Je développe une application client/serveur dans .Net 3.5 en utilisant WCF. Fondamentalement, un service client de longue durée (sur plusieurs machines) établit une connexion duplex au serveur via un netTcpBinding. Le serveur utilise ensuite le contrat de rappel du client pour effectuer certaines opérations à la demande, auxquelles le client répond de manière asynchrone (ce qui est assez standard, je pense). Je sous-classe la classe DuplexClientBase pour gérer la plupart des communications.Comment rétablir automatiquement un canal duplex en cas de panne?

Malheureusement, quand quelque chose va mal à chaque extrémité (comme une défaillance du réseau, exception inattendue, etc.), le canal se reprocher/avorté et toutes les opérations ultérieures échouent. J'ai contourné cette limitation dans les canaux non-duplex en créant une classe RecoveringClientBase qui prend automatiquement en charge lorsque le client a bloqué et réessaye l'opération.

Donc ma question est, est-il un moyen établi de déterminer quand un canal duplex est en défaut? Où dois-je vérifier ceci, sur le serveur ou le client? A défaut, quelles options ai-je pour faire en sorte que la connexion soit rétablie?

Mise à jour: Je recherche des conseils spécifiques aux canaux duplex, où le serveur pourrait essayer d'utiliser un canal de rappel défectueux. Ainsi, j'ai besoin de quelque chose qui se reconnectera/se réabrènera immédiatement quand quelque chose arrivera à la chaîne. En ce moment, j'écoute l'événement Closing de la chaîne et je le recrée si l'état est tout sauf fermé. Il fonctionne en quelque sorte, mais il se sent aki ...

Répondre

1

Nicolas Allen, de l'équipe WCF a des suggestions pour cela:

http://blogs.msdn.com/drnick/archive/2007/11/05/custom-transport-retry-logic.aspx

Sa suggestion est de gérer cela au niveau du canal. Le niveau de canal est un peu plus agréable, puisque vous pouvez le brancher dans la pile de n'importe quelle liaison via des comportements au lieu de requérir une classe de base client personnalisée.

+3

Pouvez-vous fournir un exemple de cela? L'article suggère simplement l'idée, mais ne donne aucune idée quant à la mise en œuvre. – Jacob

+0

+1 Jacob. Quelqu'un at-il des informations sur la façon de faire ce travail? J'ai actuellement dû utiliser le proxy dynamique Castle pour implémenter mon comportement de reconnexion, mais je préfèrerais plutôt ajouter ce comportement via Wcf. Je lis divers blogs Wcf mais il est impénétrable et je n'ai aucune idée par où commencer - même les extensions simples semblent nécessiter de créer des tas de classes et des ramifications de configuration - c'est déconcertant. –

+0

Ajoutez un gestionnaire d'événement à l'événement Faulted via l'interface ICommunicationObject explicite de votre service. Dans le gestionnaire d'événements, Abandonnez() le canal et créez un nouveau canal. – Jakub

0

J'ai eu des problèmes similaires, et pour moi il semble que ces appels de longue durée sont plus ou moins pris en charge.

WCF semble être conçu pour être utilisé pour des appels à court terme. Les services, qui s'appellent, font de petites choses et sont finis.

J'ai refaçonné mes applications en plus petits travaux. Donc, au lieu d'un gros article de longue durée, j'ai maintenant beaucoup de petits objets. Bien sûr, parfois cela n'est pas possible. Ensuite, je dois prier pour des connexions réseau stables (des exceptions peuvent être attrapées, donc les failles ne sont pas vraiment un problème je pense).

3

J'ai eu des problèmes lors de sessions de longue durée (minutes-heures). Je ne peux pas être sûr que c'est WCF, je suis assez sûr que son niveau de réseau. J'envisage de supprimer totalement le duplex. C'est une véritable nuisance d'essayer de gérer l'état de la connexion.

Je pense à l'hébergement d'un point de terminaison de service sur le client pour les opérations qui font actuellement partie du contrat de rappel. Le client contacterait le serveur avec les détails du point de terminaison, le serveur peut les stocker quelque part (persistant ou n'importe où). Lorsque le serveur doit contacter le client, il ouvre une connexion au client via les détails du point de terminaison. Fondamentalement, en tournant la connexion duplex en 2 connexions client-serveur. Je ne réponds pas à votre question, mais je ressens votre douleur.

0

Je pense que vous devriez vraiment écouter sur l'événement fautif. Vous pouvez écouter sur les deux extrémités, la fin du client, je pense que vous êtes déjà en charge, la fin du serveur est OperationContext.Current.Channel.events.

Je n'ai pas trouvé un moyen de renvoyer un message automatiquement car votre canal de rappel est déjà défaillant et vous ne connaissez pas encore le nouveau canal de rappel, mais vous devez garder ces appels quelque part sur le serveur jusqu'à ce que le client se reconnecte.

Les clients seront éventuellement fautifs et devraient refaire une poignée de main avec le serveur, qui est le point serveur devrait envoyer des appels non envoyés. Fondamentalement, la seule façon de récupérer à partir d'un canal défectueux/fermé est de le remplacer par un nouveau, cependant, la partie la plus importante est que vous devriez vraiment détecter la déconnexion ON TIME, j'ai trouvé activer une session fiable va déclencher un événement défaillant temps la plupart du cas. Vous pouvez également envoyer des messages de pulsation aux deux extrémités pour «tester» le canal défectueux.

Questions connexes