5 votes

Comprendre le comportement de relance de session fiable de WCF

J'ai plusieurs questions sur la fiabilité des sessions WCF :

  1. Est-ce que WCF re-sérialise un message pendant une tentative de réessayer ?

    ~~2. Si le point 1 est correct, cela se produit-il après que les paramètres du message ont été éliminés ou non ?
    3. Si le point 2 est correct, y a-t-il un moyen d'identifier avec certitude que le message a été envoyé ?~~

Je n'ai pas encore pu comprendre cela via le réflecteur.

UPD 1 : Je suis plus intéressé par les valeurs de retour du serveur. Que leur arrive-t-il ?

UPD 2 : Quand les paramètres du message (pour être précis - réponse du serveur) sont-ils disposés ? Est-ce que cela se produit lorsque les réponses appropriées sont reçues ? Voici ce que j'entends par "élimination des paramètres" :

at MyNamespace.MyReply.Dispose()
   at System.ServiceModel.Dispatcher.MessageRpc.DisposeParametersCore()
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
   at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
   at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Diagnostics.Utility.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
   at System.ServiceModel.Channels.InputQueue`1.AsyncQueueReader.Set(Item item)
   at System.ServiceModel.Channels.InputQueue`1.Dispatch()
   at System.ServiceModel.Channels.InputQueueChannel`1.Dispatch()
   at System.ServiceModel.Channels.ReliableReplySessionChannel.ProcessSequencedMessage(RequestContext context, String action, WsrmSequencedMessageInfo info)
...stack continues

J'ai besoin de l'utiliser pour disposer de la réponse du serveur (j'ai un autre fil SOF sur les raisons qui m'ont amené à cette solution).

UPD 3 : Le problème que j'essaye de résoudre est qu'elle semble que la réponse de mon serveur est d'abord éliminée, puis que l'application tente de la sérialiser. Je suis sûr à 99 % que je ne réutilise pas le même objet ailleurs. Les Stacktraces sont plutôt moches et volumineux à poster ici.

7voto

marc_s Points 321990

Non, WCF fait pas reserialise le message.

Voici ce qui se passe (de manière simplifiée) : pendant une session, chaque message envoyé par le client est mis en mémoire tampon sur le client. Par défaut, il y a de la place pour 32 messages (cela peut être modifié, et il y a aussi un tampon du côté du service).

Le message est ensuite envoyé au serveur, et s'il arrive à bon port et est distribué, le serveur envoie une confirmation et le client retire le message du tampon.

Toutefois, si le client a envoyé les messages 15 et 16, et qu'il obtient ensuite une confirmation pour le message 16 (mais pas pour le message 15), le message 15 est renvoyé à partir du tampon.

Il existe un certain nombre d'options que vous pouvez configurer, par exemple si vous souhaitez ou non une livraison ordonnée, combien de fois le client doit réessayer d'envoyer un message, etc.

Consultez ces articles et ce blog pour en savoir plus :

J'espère que cela aidera à clarifier un peu les choses

MISE À JOUR des réponses : extraites du premier article (sur MSDN) que j'ai référencé :

Si nous supposons avoir un modèle de communication le modèle de communication, la réponse doit être délivrée de manière tout aussi fiable que la demande et donc la partie partie qui répond doit mettre en œuvre un mécanisme d'initiateur qui est très similaire à celui que la partie requérante met en œuvre pour les demandes originales. La partie requérante, à son tour, joue joue le rôle d'accepteur pour les réponses. Si les réponses se perdent, elles doivent être renvoyées par la partie qui répond et donc elles doivent aussi être mises en cache (et accuser réception). Les deux extrémités d'une session de messagerie fiable maintenir des caches séparés pour les messages et les messages entrants.

Donc oui, la même chose s'applique aux réponses, également - ce qui fonctionne bien tant que nous avons une communication bidirectionnelle comme sur NetTCP ou HTTP - comme mentionné dans l'article, cela devient un peu plus délicat dans le cas d'une opération à sens unique - voir l'article pour plus de détails.

Marc

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X