Aka*_*ava 42 asp.net iis download
我不是在寻找数据库中流文件内容的替代方案,事实上我正在寻找问题的根源,这是运行文件直到IIS 6我们在经典模式下运行我们的应用程序,现在我们将IIS升级到7我们是在管道模式下运行应用程序池并且此问题已启动
我有一个处理程序,我必须向客户端请求提供大文件.我面临以下问题,
文件平均大小为4到100 MB,因此我们考虑80MB文件下载案例.
缓冲,缓慢启动
Response.BufferOutput = True;
Run Code Online (Sandbox Code Playgroud)
这导致文件启动非常慢,因为用户下载甚至进度条直到几秒钟才出现,通常是3到20秒,原因是,IIS首先读取整个文件,确定内容长度然后开始文件传输.文件正在视频播放器中播放,并且运行速度非常慢,但iPad仅先下载文件的一小部分,因此它可以快速运行.
缓冲关闭,无内容长度,快速启动,无进度
Reponse.BufferOutput = False;
Run Code Online (Sandbox Code Playgroud)
这导致立即启动,但最终客户端(典型的浏览器,如Chrome)不知道内容长度,因为IIS也不知道,因此它不显示进度,而是说下载了X KB.
缓冲关闭,手动内容长度,快速启动,进度和协议违规
Response.BufferOutput = False;
Response.AddHeader("Content-Length", file.Length);
Run Code Online (Sandbox Code Playgroud)
这样可以在Chrome等中立即正确下载文件,但在某些情况下,IIS处理程序会导致"远程客户端关闭连接"错误(这种情况非常频繁),而其他WebClient会导致协议违规.这发生在所有请求的5%到10%,而不是每个请求.
我想发生的事情是,当我们不进行缓冲时,IIS不会发送任何名为100的内容,并且客户端可能断开连接而不期望任何输出.但是,从源读取文件可能需要更长的时间,但在客户端我增加了超时但似乎IIS超时并且无法控制.
无论如何,我可以强制响应发送100继续,不让任何人关闭连接?
UPDATE
我在Firefox/Chrome中找到了以下标题,这里似乎没有任何异常的协议违规或坏标题.
Access-Control-Allow-Headers:*
Access-Control-Allow-Methods:POST, GET, OPTIONS
Access-Control-Allow-Origin:*
Access-Control-Max-Age:1728000
Cache-Control:private
Content-Disposition:attachment; filename="24.jpg"
Content-Length:22355
Content-Type:image/pjpeg
Date:Wed, 07 Mar 2012 13:40:26 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Run Code Online (Sandbox Code Playgroud)
更新2
转向回收仍然没有提供太多,但我已经将我的MaxWorkerProcess增加到8,现在我的错误数量减少了.
但平均而言,在一秒内有200个请求,2到10个请求失败..,这几乎每隔一秒发生一次.
更新3
继续5%的请求失败"服务器提交了协议违规.部分= ResponseStatusLine",我有另一个程序从使用WebClient的网络服务器下载内容,并且平均每次发出4-5次这个错误有5%的请求失败.无论如何都有追踪WebClient的失败?
问题重新定义
收到零字节文件
IIS由于某种原因关闭连接,在WebConfig的客户端,我收到0字节的文件,这不是零字节,我们做SHA1哈希检查,这告诉我们在IIS Web服务器中,没有记录错误.
这是我的错误,它解决了因为我们正在使用Entity Framework,它正在读取脏(未提交的行),因为读取不在事务范围内,将其放入事务范围已解决此问题.
提升协议违规例外
WebClient抛出WebException,说"服务器提交了协议违规.Section = ResponseStatusLine.
我知道我可以启用不安全的头解析,但这不是重点,当它是我的HTTP处理程序发送正确的标头,不知道为什么IIS发送任何额外的(在Firefox和Chrome上检查,没有什么异常),这只发生2百分之几.
更新4
发现sc-win32 64错误,我在某处读到MinBytesPerSecond的WebLimits必须从240更改为0,仍然一切都是相同的.但是我注意到,每当IIS记录64个sc-win32错误时,IIS就会将HTTP状态记录为200但是有一些错误.现在我无法打开200的Failed Trace Logging,因为它会导致大量文件.
通过增加MinBytesPerSecond以及禁用Sessions来解决上述两个问题,我已经添加了详细的答案,总结了每一点.
Aka*_*ava 12
虽然在IIS中传递大文件的正确方法是以下选项,
Ari*_*tos 11
当您使用bufferOutput设置内容长度为false时,失败的可能原因是因为IIS尝试gzip您发送的文件,并通过设置Content-Length IIS无法将其更改回压缩文件,并且错误开始(*).
所以keep the BufferOutput to false, and second disable the gzip from iis for the files you send- 或者为所有文件禁用iis gzip,然后以编程方式处理gzip部分,避免gzip发送你发送的文件.
出于同样的原因,一些类似的问题: 在加载平衡的服务器上,ASP.NET站点有时会在页面顶部冻结和/或显示奇怪的文本
HTTP压缩:某些外部脚本/ CSS在某些时候没有正确解压缩
(*)为什么不再改变它?因为从您设置标题的那一刻起您就无法参与,除非您在IIS上启用了此选项并且认为标题尚未准备好发送到浏览器.
如果没有gziped,我想到的下一件事是文件被发送,并且由于某种原因连接被延迟,并且超时并关闭.所以你得到"远程主机关闭连接".
这可以根据原因解决:
如果它来自IIS,请转到网站属性并确保设置最大的"连接超时"和"启用HTTP保持活动".
通过更改web.config来更新页面(您可以仅以编程方式更改一个特定页面)
<httpRuntime executionTimeout="43200"
Run Code Online (Sandbox Code Playgroud)
另请查看:http: //weblogs.asp.net/aghausman/archive/2009/02/20/prevent-request-timeout-in-asp-net.aspx
您需要检查的另一件事是不要在用于发送文件的处理程序上使用会话,因为会话锁定操作直到完成,如果用户需要更长的时间来下载文件,第二个可能会得到超时.
一些亲戚:
Response.WriteFile函数失败并给出504网关超时
我要做的是使用不太知名的ASP.NET Response.TransmitFile方法,因为它非常快(并且可能使用IIS内核缓存),并且可以处理所有标头内容。它基于Windows非托管TransmitFile API。
但是要能够使用此API,您需要一个物理文件进行传输。因此,这里有一个伪C#代码,解释了如何使用虚构的myCacheFilePath物理文件路径执行此操作。它还支持客户端缓存的可能性。当然,如果您已经有了一个文件,则不需要创建该缓存:
if (!File.Exists(myCacheFilePath))
{
LoadMyCache(...); // saves the file to disk. don't do this if your source is already a physical file (not stored in a db for example).
}
// we suppose user-agent (browser) cache is enabled
// check appropriate If-Modified-Since header
DateTime ifModifiedSince = DateTime.MaxValue;
string ifm = context.Request.Headers["If-Modified-Since"];
if (!string.IsNullOrEmpty(ifm))
{
try
{
ifModifiedSince = DateTime.Parse(ifm, DateTimeFormatInfo.InvariantInfo);
}
catch
{
// do nothing
}
// file has not changed, just send this information but truncate milliseconds
if (ifModifiedSince == TruncateMilliseconds(File.GetLastWriteTime(myCacheFilePath)))
{
ResponseWriteNotModified(...); // HTTP 304
return;
}
}
Response.ContentType = contentType; // set your file content type here
Response.AddHeader("Last-Modified", File.GetLastWriteTimeUtc(myCacheFilePath).ToString("r", DateTimeFormatInfo.InvariantInfo)); // tell the client to cache that file
// this API uses windows lower levels directly and is not memory/cpu intensive on Windows platform to send one file. It also caches files in the kernel.
Response.TransmitFile(myCacheFilePath)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
57999 次 |
| 最近记录: |