Question

J'ai une application client / serveur WCF qui communique via HTTP à l'aide de WSHttpBinding.

Configuration du serveur : hébergement autonome, à l'aide de la WCF standard ServiceHost. Ma classe de service actuelle est attribuée à:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, 
 InstanceContextMode = InstanceContextMode.PerSession, 
 UseSynchronizationContext = false)]

Configuration du client : utilisation d'un proxy client généré par visual-studio à l'aide d'appels de service synchrones (proxy.call_server_method blocs jusqu'à la réponse complète du serveur.)

Scénario : J'ai un appel de méthode particulier qui prend 20 secondes pour s'exécuter sur le serveur. Le client appelle cette méthode dans un thread séparé. Ainsi, elle n'est pas bloquée. ConcurrencyMode.Multiple signifie que WCF doit également l'exécuter dans un thread séparé sur le serveur.

Cette théorie est corroborée par le fait que lorsque je configure mon application pour une utilisation NetTcpBinding, tout fonctionne correctement.

Problème :
Si je configure l'application pour qu'elle utilise WSHttpBinding, cet appel de méthode long provoque la "sauvegarde" des requêtes http. J'ai vérifié ce comportement en inspectant mes journaux et en déboguant les requêtes HTTP à l'aide de fiddler.

Exemple:

  • Le client lance une requête de 20 secondes sur un thread en arrière-plan
  • Le client lance la demande B et C sur le thread de premier plan
  • Les demandes B et C sont envoyées au serveur, qui ne les traite pas avant la fin de la demande de 20 secondes

Mais parfois:

  • Les demandes B et C ne sont pas envoyées (elles n'apparaissent même pas dans le violoniste) jusqu'à ce que la demande de 20 secondes soit renvoyée (ce qui est rare).
    • Remarque: le paramétrage <add address="*" maxconnection="100"/> dans le fichier app.config du client a pour effet que cela (semble) cesser de se produire.
  • La demande B est envoyée et reçoit une réponse immédiatement, tandis que la demande C est retenue jusqu'à la fin de la demande de 20 secondes (ce qui est rare)

Voici une chronologie du violoniste démontrant le problème: (cliquez pour agrandir)

Comme vous pouvez le constater, les demandes sont toutes sauvegardées sur le serveur. Une fois que la demande de 20 secondes est terminée, toutes les réponses arrivent, mais notez qu'il y a des demandes qui ne sont pas bloquées ...

Alors, Questions :

  • Qu'est-ce qui se passe ici? Pourquoi cela fonctionne-t-il correctement avec !syncblk et non avec <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />?
  • Pourquoi ce comportement incohérent?
  • Que puis-je faire pour résoudre ce problème?

Notes:

  • Cela ne se verrouille pas sur le serveur. J'ai défini des points d'arrêt et utilisé <=> et il indique systématiquement qu'aucun verrou n'est bloqué.
  • Ce n'est pas mon thread (NetTcpBinding ne devrait pas fonctionner autrement)
  • J'ai <=> défini dans le fichier app.config du serveur
  • L'appel de 20 secondes n'attend qu'une minuterie, il ne blesse pas le processeur, le disque ou le réseau
  • Je préférerais une solution qui n'impliquait pas une nouvelle architecture de l'application pour utiliser des appels asynchrones ... c'est un gros code hérité et je ne veux vraiment pas jouer avec des choses que je ne comprends pas. .
Était-ce utile?

La solution 3

[Réponse automatique pour montrer aux autres utilisateurs quelle était notre solution éventuelle]

Au final, je n’ai jamais réussi à résoudre ce problème.
Notre dernière solution consistait à remplacer notre application de WSHttpBinding à NetTcpBinding en production - nous avions prévu de le faire de toute façon pour des raisons de performance.

C’est plutôt regrettable, car cela laisse une marque noire sur <=> qui peut ou non être justifiée. Si quelqu'un trouve jamais une solution qui n'implique pas l'abandon <=>, j'aimerais en savoir plus

.

Autres conseils

Il existe des restrictions en dehors de WCF (une fonctionnalité .Net ou Windows) qui, par défaut, ne permettent qu'un maximum de deux connexions HTTP sortantes simultanées. Malheureusement, je ne me souviens plus jamais du nom de la chose (et de ce que vous mettriez dans app.config ou votre application pour la remplacer). Étant donné que vous ne voyez pas les demandes quitter le client et qu'il s'agit uniquement de HTTP, je pense que vous frappez & "Cette chose &" ;. Je vais continuer à chercher son nom.

Mise à jour: trouvé - essayez ceci sur le client (mais changez le '2' en un plus grand nombre):

<configuration>
  <system.net>
    <connectionManagement>
      <add address = "*" maxconnection = "2" />
    </connectionManagement>
  </system.net>
</configuration>

Nous avons constaté exactement les mêmes problèmes avec un service JSON hébergé dans IIS / ASP.NET.

La cause principale a finalement été la synchronisation des requêtes par ASP.NET, et non pas par WCF. Nous avons dû désactiver l'état de session (au niveau de l'application) pour obtenir des méthodes WCF simultanées.

Web.config: <system.web> <sessionState mode="Off" /> </system.web>

Veuillez noter que notre service utilise webHttpBinding, pas wsHttpBinding. Donc, je ne sais pas si cela résoudra également le problème d'Orion.

Je pense que vous atteignez la limite du protocole. Pour contourner ce problème, vous devez modifier les paramètres standard sur la machine cliente:

http://support.microsoft.com/kb/183110

http://support.microsoft.com/kb/282402

J'imagine que WSHttpBinding utilise les paramètres WinINET lors de l'émission des demandes.

Si vous passez à BasicHttpBinding, cela fonctionne-t-il?

Dans ce cas, il semble que C’est votre problème , la limitation de session, quelque chose qui m’a mordu dans le cul.

Envisagez d’utiliser ConcurrencyMode.Multiple sur des services par appel pour autoriser les appels simultanés. appels.

J'oublie - pourrait-il s'agir d'une commande? Je pense que peut-être que RM sur http conserve l’ordre mais que les sessions Tcp ne le font pas (à moins que vous ne le demandiez explicitement)? Existe-t-il un attribut dans le contrat de service décrivant les sessions commandées / non ordonnées (je l’oublie).

Pas certain, mais parfois le problème des appels simultanés de l'application silverlight est lié à la gestion de la connexion du navigateur. Pour moi, la solution a été de mettre cela dans notre méthode App.xaml.cs, Application_Startup, comme décrit ici: http://weblogs.asp.net/olakarlsson/simultaneous-calling-multiple-methods-on-a-wcf-service-from-silverlight

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top