Comment puis-je rétablir automatiquement la liaison Named Pipe dans WCF?
Je suis en train d'écrire un service qui s'appelle à partir de l'hôte local. La Performance est importante, donc je pensais que je voudrais essayer le NetNamedPipeBinding au lieu de NetTcpBinding et voir Si je pouvais voir notable des gains de performances.
Si un client, après avoir effectué un ou plusieurs requêtes vers le serveur est inactif pendant une période de temps plus longue la prochaine demande échoue, apparemment en raison de certains temps d'inactivité dans la liaison. La même chose se produit également lorsque le service reçoit redémarré.
J'ai besoin de mes clients pour être en mesure de garder une connexion ouverte tant que c'est permis afin d'éviter les frais généraux associés à la configuration d'une nouvelle connexion. J'ai aussi besoin d'être en mesure de redémarrer le service de temps à autre et ont les clients automatiquement réessayer si ils remarquent que la connexion a été interrompue.
Je sais que c'est suppported par la fiabilité des trucs dans NetTcpBinding mais comment pourrait-on obtenir le même niveau de re-connecter la fiabilité dans le NetNamedPipeBinding? Est-il même possible?
La question est quelque peu théorique car elle n'est pas une obligation d'utiliser des NetNamedPipes, je pourrais tout aussi facilement adopter pour utiliser le protocole tcp-contraignant, mais C'est une démangeaisons et je tiens vraiment à les rayer.
source d'informationauteur Markus Olsson
Vous devez vous connecter pour publier un commentaire.
Mon expérience est que, lors de l'utilisation de NetNamedPipes, le "ReceiveTimout" sur la liaison fonctionne comme un "Délai d'Inactivité" plutôt que de recevoir un timout. Notez que cette différente de la façon dont un NetTCPBinding œuvres. Avec le protocole TCP, c'est vraiment un délai de réception (et il y en a séparé le délai d'inactivité, vous pouvez configurer via la messagerie fiable. (Il est également semble être contraire à la documentation du SDK, mais bon).
Pour résoudre ce problème, définissez la RecieveTimout à quelque chose de grand quand vous créez la liaison.
Par exemple, si vous créez votre contraignant sur le plan procédural...
Ou, si vous vous souciez de la création de votre liaison de manière déclarative...
Je n'ai pas utilisé NetNamedPipes dans WCF, mais j'ai passé plus de temps que je voulais apprendre les valeurs de délai d'attente pour NetTcp. J'utilise la suite des configs pour mon NetTcpBindings et eu de la chance avec la connexion de rester actif.
Serveur:
Client:
Les paramètres les plus importants que j'ai passé le plus de temps sont les sendTimeout et receiveTimeout. Si votre receiveTimeout est le même ou moins de votre envoi, le canal va baisser une fois que le délai est atteint. Si la réception est plus élevée et l'envoi est supérieur à un seuil, le canal du feu un niveau de transport keepalive. De mes tests, le sendTimeout seuil est de 30 secondes. Rien de moins que cela et les connexions actives ne sont pas envoyés.
En outre, j'ai un minuteur en fonction keepalive appel que j'exécute à chaque minute pour essayer et s'assurer que le canal est en place et fonctionne bien. L'appel est simplement un retour boolean membre:
Vous pouvez également récupérer les événements de canal (si vous les obtenez au bon moment) et rouvrir la connexion si quelque chose se passe mal:
J'espère un peu de cela se traduit par la et a de la valeur pour vous avec NetNamedPipes.
Edit: Plus d'options pour capturer le serveur redémarré question
Lorsque le serveur redémarre, il doit amener le client, canal, soit de près ou de faute. La capture de ces événements sur le côté client serait vous donner la possibilité de reconnecter à l'aide de la minuterie jusqu'à ce que le service est de nouveau disponible.
Vous voulez assurer la reconnexion du timer de tentatives de connexion sont fait sur un thread d'arrière-plan de manière asynchrone, afin qu'ils ne pas accrocher l'INTERFACE utilisateur chaque fois qu'ils tentent de se connecter. YMMV
J'ai été à la recherche dans le problème des pertes de connexions TCP pour les deux jours maintenant et sont venus à la conclusion que beaucoup de gens sont en manque un point crutial lors de la configuration de connexions dans WCF. Ce que tout le monde semble être en train de faire est de créer un canal une fois, puis en essayant de s'accrocher à elle pour la durée de vie de l'application, en jouant toutes sortes de sales astuces pour garder la session TCP vivant. Ce n'est pas la façon dont il était censé être.
Vous devez créer un canal, effectuez l'une (ou un peu plus, peu de temps après la première) à des appels sur votre service, puis fermez-les et jetez le canal. Cela va vous donner (presque) apatrides opération, et vous n'avez pas à être dérangé à la tenue de séances en vie, vous ne devriez pas vouloir en premier lieu.
Vous trouverez que la surcharge de la création et de fermeture d'un canal (à partir d'un réutilisés ChannelFactory) est négligeable, ne prenant que quelques dizaines de nanosecondes sur une machine typique.
La receiveTimeout attribut que tout le monde est du démarrage définit le temps d'un canal peut rester inactive avant d'être automatiquement abandonnée, ce qui vous indique les canaux ne sont pas destinés à rester ouverts pendant très longtemps (la valeur par défaut est de 1 minute). Si vous définissez receiveTimeout de Temps.MaxValue il gardera votre ouverture de canal plus, mais ce n'est pas ce qu'il est, ni ce que vous voulez dans un scénario pratique.
Ce qui finalement m'a mis sur la voie de droite a été
http://msdn.microsoft.com/en-us/library/ms734681.aspx
qui fournit un horriblement buggé exemple, mais ne leur montrer comment il faut aller sur l'aide de ChannelFactory. Les intervenants soulignent les bugs et de régler les pendules à l'heure, donc, en tout, vous pouvez obtenir tout ce dont vous avez besoin ici.
Et puis, tous mes problèmes ont été plus de. Pas plus "Une opération a été tentée sur autre chose qu'un socket" et non plus "Une connexion existante a dû être fermée par l'hôte distant".