什么130秒超时killig我的WCF流媒体服务电话吗? [英] What 130 second timeout is killig my WCF streaming service call?

查看:703
本文介绍了什么130秒超时killig我的WCF流媒体服务电话吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

就在最近,我开始调查一个棘手的问题,WCF数据流中,如果客户端等待之间发送到服务器不再超过130秒的CommunicationException就产生了。

下面是完整的异常:

  System.ServiceModel.CommunicationException是未处理由用户code
  HResult的= -2146233087
  消息=套接字连接被中止。这可能是一个错误处理您的信息或接收超时导致被超过的远程主机,或者潜在的网络资源问题。本地套接字超时是'23:59:59.9110000。
  来源= mscorlib程序
  堆栈跟踪:
    服务器堆栈跟踪:
       在System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.WebRequestOutputStream.Write(字节[]缓冲区的Int32偏移的Int32计数)
       在System.IO.BufferedStream.Write(byte []数组,的Int32偏移的Int32计数)
       在System.Xml.XmlStreamNodeWriter.FlushBuffer()
       在System.Xml.XmlStreamNodeWriter.GetBuffer(的Int32计数,的Int32和放大器;偏置)
       在System.Xml.XmlUTF8NodeWriter.InternalWriteBase64Text(字节[]缓冲区的Int32偏移的Int32计数)
       在System.Xml.XmlBaseWriter.WriteBase64(字节[]缓冲区的Int32偏移的Int32计数)
       在System.Xml.XmlDictionaryWriter.WriteValue(IStreamProvider值)
       在System.ServiceModel.Dispatcher.StreamFormatter.Serialize(的XmlDictionaryWriter作家,对象[]参数,对象的returnValue)
       在System.ServiceModel.Dispatcher.OperationFormatter.OperationFormatterMessage.OperationFormatterBodyWriter.OnWriteBodyContents(XmlDictionaryWriter作家)
       在System.ServiceModel.Channels.Message.OnWriteMessage(的XmlDictionaryWriter作家)
       在System.ServiceModel.Channels.TextMessageEn coderFactory.TextMessageEn coder.WriteMessage(消息消息,涧流)
       在System.ServiceModel.Channels.HttpOutput.WriteStreamedMessage(时间跨度超时)
       在System.ServiceModel.Channels.HttpOutput.Send(时间跨度超时)
       在System.ServiceModel.Channels.HttpChannelFactory`1.Htt$p$pquestChannel.HttpChannelRequest.SendRequest(Message消息,时间跨度超时)
       在System.ServiceModel.Channels.RequestChannel.Request(消息的消息,时间跨度超时)
       在System.ServiceModel.Channels.ServiceChannel.Call(串动,布尔单向,ProxyOperationRuntime操作,对象[]插件,对象[]出局,时间跨度超时)
       在System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime操作)
       在System.ServiceModel.Channels.ServiceChannelProxy.Invoke(即时聊天消息)
    异常重新抛出的[0]
       在System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天reqMsg,即时聊天retMsg)
       在System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&安培; MSGDATA,的Int32型)
       在WcfService.IStreamingService.SendStream(MyStreamU prequest要求)
       在Client.Program<主> b__0()在C:\ Users \用户jpierson \文档\的Visual Studio 2012 \项目\ WcfStreamingTest \客户\的Program.cs:行44
       在System.Threading.Tasks.Task.Execute()
  的InnerException信息:System.IO.IOException
       HResult的= -2146232800
       消息=无法将数据写入传输连接:一个现有的连接被强行关闭远程主机。
       来源=系统
       堆栈跟踪:
            在System.Net.Sockets.NetworkStream.MultipleWrite(BufferOffsetSize []缓冲区)
            在System.Net.ConnectStream.InternalWrite(布尔异步,字节[]缓冲区的Int32偏移的Int32大小,AsyncCallback的回调,对象的状态)
            在System.Net.ConnectStream.Write(字节[]缓冲区的Int32偏移的Int32大小)
            在System.ServiceModel.Channels.BytesReadPositionStream.Write(字节[]缓冲区的Int32偏移的Int32计数)
            在System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.WebRequestOutputStream.Write(字节[]缓冲区的Int32偏移的Int32计数)
       的InnerException:System.Net.Sockets.SocketException
            HResult的= -2147467259
            消息=一个现有的连接被远程主机强行关闭
            来源=系统
            错误code = 10054
            NativeError code = 10054
            堆栈跟踪:
                 在System.Net.Sockets.Socket.MultipleSend(BufferOffsetSize []缓冲区的SocketFlags的SocketFlags)
                 在System.Net.Sockets.NetworkStream.MultipleWrite(BufferOffsetSize []缓冲区)
            的InnerException:
 

看来,服务器已关闭了连接prematurely由于不活动的连接。如果我不是给一个脉冲到服务器,在同一时间,即使一个字节,然后我从来没有得到这个例外,我可以继续无限期地传输数据。我已经构建了一个非常简单的示例应用程序,以证明这一点,它使用basicHttpBinding的与流媒体transferMode和我插入来自内延迟130秒的客户端上的自定义流实现人为的延迟。这模拟类似于在该流在我的服务呼叫从客户机提供的所述数据不供给到WCF基础结构足够快,以满足某种不可识别的超时值,似乎是绕130秒的缓冲欠载运行状态的东西标记。

使用WCF服务跟踪工具,我能找到的一条消息,读取HttpException客户端已断开连接,因为基础请求已完成,不再有可用的HttpContext的。

这是我看到的一个条目,说IIS防爆preSS跟踪日志文件的I / O操作已中止,因为一个线程退出或应用程序请求。(0x800703e3)

我已经配置了服务器和客户机超时了130秒大关使用的值也只是来统治他们。我试过的idleTimeout在IIS防爆preSS和主机ASP.NET相关的超时值太大,以发现哪里这个问题是来自,但至今没有运气。我能找到到目前为止最好的资料是由开发人员的在Firefox的问题跟踪一个注释描述了一个类似的问题在WCF架构之外的工作。出于这个原因,我猜想问题可能更多的是IIS7的或可能的Windows Server相关的具体。

在服务器上的Web.config自定义绑定

 <绑定名称=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 =流媒体/>
< /装订>
 

在code客户端配置:

  VAR结合=新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);
 

在回应WALS主意,尝试看看,如果我得到自我托管我的服务有什么不同的结果我想补充一点,我这样做了,我发现我得到相同的结果,如IIS托管时。这是什么意思?我的猜测是,这意味着问题是无论是在WCF或在Windows底层的网络基础设施。我使用的是Windows 7 64位,我们已经通过运行各种客户端,并在Windows 2008 Server上运行该服务部发现了这个问题。

更新2013年1月15日

我发现了一些新的线索感谢DarkWanderer一旦我意识到,WCF使用HTTP.sys将在Windows 7自托管的情况下这让我寻找到了什么,我可以配置HTTP.sys进行,也问题的人是什么类型的报导说,对于那些听起来相似什么我遇到的HTTP.sys。这导致我到位于日志文件中的 C:\ WINDOWS \ SYSTEM32 \ LogFiles文件\ HTTPERR \ httperr1.log 的出现登录特定类型的HTTP问题上的HTTP.sys的一部分。在此日志我看到了以下类型的日志条目的每一个我跑我的测试时间。

  

2013年1月15日17点17分12秒127.0.0.1 127.0.0.1 59111 52733 HTTP / 1.1 POST   /StreamingService.svc - - Timer_EntityBody -

所以它的下跌寻找什么样的条件可能会导致href="http://support.microsoft.com/kb/820729#3"> Timer_EntityBody 的错误,什么设置在IIS7或其他地方可能有一个

官方网站IIS

  

连接过期之前到达请求实体正文。当   清楚的是,请求具有一个实体主体,所述HTTP API接通   Timer_EntityBody计时器。最初,该定时器的限制设定为   ConnectionTimeout值。每当另一个数据指示   在此请求中接收,在HTTP的API重置计时器,得到   在为ConnectionTimeout指定的连接多分钟   属性。

尝试修改为ConnectionTimeout属性作为参考上述建议在对ApplicationHost.config的IIS防爆preSS似乎没有任何区别。也许IIS防爆preSS忽略此配置,并采用了硬codeD值内?尝试一些我自己我发现有添加,显示,并添加超时值,以便让我去,我想出了下面的命令,但不幸的是这样做似乎没有对这个错误有什么影响或者新的netsh HTTP命令。

  

netsh的HTTP加上超时timeouttype = IdleConnectionTimeout值= 300

解决方案

事实证明,这个问题是由引起的<一个href="http://www.iis.net/configreference/system.applicationhost/sites/sitedefaults/limits">Connection使用由HTTP.sys进行超时值,可以通过通过高级设置IIS管理器不同地点的规定。此值由默认配置成当两个头部和主体没有被120秒内接收到超时的连接。如果接收到的数据从所述主体的脉冲然后在服务器重启的定时器(Timer_EntityBody)的超时值内,则定时器复位以等待附加数据

这是一样有关文件 Timer_EntityBody connectionTimeout 指定,但它很难,因为它似乎是IIS防爆preSS忽略了限制元素中指定ConnectionTimeout值精确定位的对ApplicationHost.config 的不管是什么该文件说。为了确定这一点,我不得不对我的开发机器上安装完整版本的IIS和修改上述托管我的网站出现后设置。

由于我们是东道主IIS下的真正的服务在Windows 2008以上的解决方案将工作对我来说可是问题仍然存在如何正确修改情况下,连接超时值,其中你是自托管。

Just recently I started to investigate a tricky problem with WCF streaming in which a CommunicationException is produced if the client waits for any longer than 130 seconds in between sends to the server.

Here is the full 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: 

It appears that the server has closed the connection prematurely due to inactivity on the connection. If I instead give a pulse to the server, even one byte at a time, then I never get this exception and I can continue to transfer data indefinitely. I've constructed a very simple example application to demonstrate this which uses basicHttpBinding with Streamed transferMode and I insert an artificial delay from within a custom stream implementation on the client that delays for 130 seconds. This simulates something similar to a buffer under-run condition in which the stream provided in my service call from the client is not feeding the data to the WCF infrastructure quick enough to satisfy some sort of unidentifiable timeout value that appears to be around the 130 second mark.

Using the WCF service tracing tools I'm able to find an HttpException with the a message that reads "The client is disconnected because the underlying request has been completed. There is no longer an HttpContext available."

From the IIS Express trace log file I see an entry that says "The I/O operation has been aborted because of either a thread exit or an application request. (0x800703e3)"

I've configured both server and client timeouts to use a value well over the 130 second mark just to rule them out. I've tried idleTimeout in IIS Express and a host of ASP.NET related timeout values too in order to discover where this issue is coming from but so far no luck. The best information I can find so far is a comment in the FireFox issue tracker by a developer that describes a similar problem working outside of the WCF architecture. For this reason I'm guessing the issue may be more related specifically to IIS7 or possibly Windows Server.

Custom binding on server 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>

Client side configuration in 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);

In response to wals idea to try to see if I get any different results by self hosting my service I want to add that I did so and found that I get the same results as when hosting in IIS. What does this mean? My guess is that this means the issue is either in WCF or in the underlying networking infrastructure in Windows. I'm using Windows 7 64 bit and we've discovered this issue by running various clients and running the service portion on a Windows 2008 Server.

Update 2013-01-15

I found some new clues thanks to DarkWanderer once I realized that WCF uses HTTP.sys underneath in self-hosting scenarios on Windows 7. This got me looking into what I could configure for HTTP.sys and also what type of issues people are reporting that for HTTP.sys that sound similar to what I'm experiencing. This lead me to a log file located at C:\Windows\System32\LogFiles\HTTPERR\httperr1.log which appears to log specific types of HTTP issues on the part of HTTP.sys. In this log I see the following type of log entry each time I run my 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 -

So it's down to finding what conditions could cause a Timer_EntityBody error and what settings in IIS7 or elsewhere may have a bearing on when and if that error occurs.

From the official IIS webiste:

The connection expired before the request entity body arrived. When it is clear that a request has an entity body, the HTTP API turns on the Timer_EntityBody timer. Initially, the limit of this timer is set to the connectionTimeout value. Each time another data indication is received on this request, the HTTP API resets the timer to give the connection more minutes as specified in the connectionTimeout attribute.

Trying to modify the connectionTimeout attribute as the reference above suggests for in applicationhost.config for IIS Express doesn't seem to make any difference. Perhaps IIS Express ignores this configuration and uses a hard coded value internally? Trying something on my own I discovered that there are new netsh http commands added to show and add timeout values so giving that I go I came up with the following command but unfortunately doing so didn't seem to have any effect on this error either.

netsh http add timeout timeouttype=IdleConnectionTimeout value=300

解决方案

It turns out that this issue was caused by the Connection Timeout value used by HTTP.sys and that can be specified through IIS Manager through the Advanced Settings for the individual site. This value is configured by default to timeout a connection when both the header and body haven't been received within 120 seconds. If a pulse of data from the body is received then the server restarts a timer (Timer_EntityBody) within the timeout value then the timer is reset to wait for additional data.

This is just as the documentation concerning Timer_EntityBody and connectionTimeout specifies, however it was hard to pinpoint because it appears that IIS Express ignores the connectionTimeout value specified in the limits element in applicationhost.config regardless of what the documentation says. In order to determine this I had to install the full version of IIS on my development machine and modify the setting above after hosting my site there.

Since we are hosting the real service under IIS on Windows 2008 the above solution will work for me however the question still remains on how to properly modify the Connection Timeout value in cases where you are Self Hosting.

这篇关于什么130秒超时killig我的WCF流媒体服务电话吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆