Quel délai de 130 secondes met fin à mon appel de service de streaming WCF?

Tout récemment, j'ai commencé à enquêter sur un problème délicat avec WCF en streaming dans laquelle un CommunicationException est produit si le client attend plus de 130 secondes entre les envoie au serveur.

Ici, c'est la pleine exception:

System.ServiceModel.CommunicationException was unhandled by user code
HResult=-2146233087
Message=The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '23:59:59.9110000'.
Source=mscorlib
StackTrace:
Server stack trace: 
at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.WebRequestOutputStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.IO.BufferedStream.Write(Byte[] array, Int32 offset, Int32 count)
at System.Xml.XmlStreamNodeWriter.FlushBuffer()
at System.Xml.XmlStreamNodeWriter.GetBuffer(Int32 count, Int32& offset)
at System.Xml.XmlUTF8NodeWriter.InternalWriteBase64Text(Byte[] buffer, Int32 offset, Int32 count)
at System.Xml.XmlBaseWriter.WriteBase64(Byte[] buffer, Int32 offset, Int32 count)
at System.Xml.XmlDictionaryWriter.WriteValue(IStreamProvider value)
at System.ServiceModel.Dispatcher.StreamFormatter.Serialize(XmlDictionaryWriter writer, Object[] parameters, Object returnValue)
at System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.Message.OnWriteMessage(XmlDictionaryWriter writer)
at System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Stream stream)
at System.ServiceModel.Channels.HttpOutput.WriteStreamedMessage(TimeSpan timeout)
at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]: 
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at WcfService.IStreamingService.SendStream(MyStreamUpRequest request)
at Client.Program.<Main>b__0() in c:\Users\jpierson\Documents\Visual Studio 2012\Projects\WcfStreamingTest\Client\Program.cs:line 44
at System.Threading.Tasks.Task.Execute()
InnerException: System.IO.IOException
HResult=-2146232800
Message=Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.
Source=System
StackTrace:
at System.Net.Sockets.NetworkStream.MultipleWrite(BufferOffsetSize[] buffers)
at System.Net.ConnectStream.InternalWrite(Boolean async, Byte[] buffer, Int32 offset, Int32 size, AsyncCallback callback, Object state)
at System.Net.ConnectStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.ServiceModel.Channels.BytesReadPositionStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.WebRequestOutputStream.Write(Byte[] buffer, Int32 offset, Int32 count)
InnerException: System.Net.Sockets.SocketException
HResult=-2147467259
Message=An existing connection was forcibly closed by the remote host
Source=System
ErrorCode=10054
NativeErrorCode=10054
StackTrace:
at System.Net.Sockets.Socket.MultipleSend(BufferOffsetSize[] buffers, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.MultipleWrite(BufferOffsetSize[] buffers)
InnerException: 

Il semble que le serveur a fermé la connexion prématurément en raison de l'inactivité de la connexion. Si j'ai la place donner une impulsion sur le serveur, même un octet à la fois, alors je n'obtiens jamais de cette exception et je peux continuer à transférer des données indéfiniment. J'ai construit un exemple très simple de l'application de démontrer ce qui utilise basicHttpBinding avec Streaming transferMode et j'ai insérer un délai artificiel à partir de l'intérieur d'un flux personnalisé de mise en œuvre sur le client que les délais pour 130 secondes. Cela simule quelque chose de semblable à un dépassement de mémoire tampon condition dans laquelle le flux fourni dans mon appel de service du client n'est pas de nourrir les données de la FMC de l'infrastructure assez rapide pour satisfaire une sorte de non identifiables valeur de délai d'expiration qui semble être d'environ 130 deuxième marque.

En utilisant le service WCF des outils de suivi, je suis en mesure de trouver un HttpException avec un message qui dit "Le client est déconnecté en raison de la demande sous-jacente a été achevé. Il n'est plus une HttpContext disponible."

De l'IIS Express fichier journal de suivi, je vois une entrée qui dit que "L'opération d'e/S a été annulée en raison d'une sortie de thread ou à la demande d'une application. (0x800703e3)"

J'ai configuré à la fois serveur et client délais d'attente pour utiliser une valeur de plus de 130 deuxième marque juste à la règle. J'ai essayé idleTimeout dans IIS Express et une foule de ASP.NET liés valeurs de délai d'attente trop afin de découvrir d'où ce problème vient de mais jusqu'à présent aucune chance. La meilleure information que je peux trouver à ce jour est une commentaire dans FireFox bug tracker par un développeur qui décrit un problème similaire de travailler à l'extérieur de la FMC de l'architecture. Pour cette raison, je suppose que le problème est peut-être plus spécifiquement lié à IIS7 ou, éventuellement, de Windows Server.

Liaison personnalisée sur le serveur Web.config

<binding name="myHttpBindingConfiguration"
closeTimeout="02:00:00"
openTimeout="02:00:00"
receiveTimeout="02:00:00"
sendTimeout="02:00:00">
<textMessageEncoding messageVersion="Soap11" />
<httpTransport maxBufferSize="65536"                        
maxReceivedMessageSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="Streamed" />
</binding>

Côté Client configuration dans le code:

    var binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = _maxReceivedMessageSize;
binding.MaxBufferSize = 65536;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.TransferMode = TransferMode.Streamed;
binding.ReceiveTimeout = TimeSpan.FromDays(1);
binding.OpenTimeout = TimeSpan.FromDays(1);
binding.SendTimeout = TimeSpan.FromDays(1);
binding.CloseTimeout = TimeSpan.FromDays(1);

En réponse à wals idée d'essayer de voir si j'obtiens des résultats différents par l'auto-hébergement de mon service, j'ai envie d'ajouter que je l'ai fait et constaté que j'obtiens les mêmes résultats que lors de l'hébergement dans IIS. Qu'est-ce que cela signifie? Je suppose que cela signifie que le problème est soit dans WCF ou dans le sous-jacent de l'infrastructure de réseau dans Windows. Je suis sous Windows 7 64 bits, et nous avons découvert ce problème en exécutant divers clients et l'exécution de la partie sur un Serveur Windows 2008.

Mise à jour 2013-01-15

J'ai trouvé quelques nouveaux indices grâce à DarkWanderer une fois que j'ai réalisé que WCF utilise HTTP.sys en dessous de l'auto-hébergement scénarios sur Windows 7. Cela m'a regarder dans ce que j'ai pu configurer pour HTTP.sys et aussi quel type de problèmes que les gens sont des rapports que pour HTTP.sys que son semblable à ce que je suis en train de vivre. Cela me conduirait à un fichier journal situé à C:\Windows\System32\LogFiles\HTTPERR\httperr1.log qui apparaît à certains types de HTTP sur les problèmes de HTTP.sys. Dans ce journal, je vois le type d'entrée de journal chaque fois que je lance mon test.

2013-01-15 17:17:12 127.0.0.1 59111 127.0.0.1 52733 HTTP/1.1 POST
/StreamingService.svc - - Timer_EntityBody -

Donc, c'est vers le bas pour trouver quelles conditions pourrait causer un Timer_EntityBody erreur et quels sont les paramètres dans IIS7 ou ailleurs peuvent avoir une incidence sur le moment et si cette erreur se produit.

De la officiel site web IIS:

La connexion a expiré avant que la demande de l'entité arrivée du corps. Quand il
est clair qu'une demande a un corps d'entité, l'API HTTP de tours sur le
Timer_EntityBody de la minuterie. D'abord, la limite de ce que la minuterie est réglée à
la valeur connectionTimeout. Chaque fois qu'un autre indication de données
reçu sur cette demande, l'API HTTP réinitialise la minuterie pour donner l'
connexion de plusieurs minutes, comme spécifié dans le connectionTimeout
attribut.

Essayer de modifier le connectionTimeout attribut comme la référence ci-dessus suggère pour en applicationhost.config pour IIS Express ne semblent pas faire la différence. Peut-être IIS Express ignore cette configuration et utilise une valeur codée en dur interne? Essayer quelque chose sur mon propre j'ai découvert qu'il y a de nouvelles commandes netsh http ajouté pour afficher et ajouter des valeurs de délai d'attente, si généreux que je vais je suis venu avec la commande suivante, mais malheureusement, le faire ne semble pas avoir d'effet sur cette erreur.

netsh http ajoutez délai timeouttype=IdleConnectionTimeout valeur=300

source d'informationauteur jpierson