我正在开发 Azure 中的 Web 服务框架以及与 Azure 通信的网站。网站应使用文件名调用 Azure,Azure 中的 Web 服务应在 Blob 存储中找到给定文件并将其发送回客户端以供下载。
只要返回的文件很小(使用 20mb mp4 文件进行测试效果很好),我就可以让它工作,但像 1Gb mp4 文件这样的文件最终会抛出异常。
C# 请求代码:
public override async Task ProcessRequestAsync(HttpContext context)
{
JavaScriptSerializer oSearlizer = new JavaScriptSerializer();
object o = new
{
sourceStorageAccountName = "accountName",
sourceStorageAccountKey = "accountKey",
sourceContainer = "test"
};
string req = oSearlizer.Serialize(o);
HttpContent content = new StringContent(req, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
HttpResponseMessage x = await client.PostAsync("http://localhost:7071/api/get_file", content);
context.Response.Clear();
context.Response.Buffer = false;
context.Response.BufferOutput = false;
context.Response.ContentType = "video/mp4";
context.Response.AddHeader("content-disposition", "attachment;filename=test.mp4"); // Save file
context.Response.Charset = "";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.BinaryWrite(await x.Content.ReadAsByteArrayAsync());
context.Response.End();
}
Azure Web 服务代码:
CloudBlobContainer sourceBlobContainer = CopyBlobHelpers.GetCloudBlobContainer(_sourceStorageAccountName, _sourceStorageAccountKey, _sourceContainer);
CloudBlockBlob blob = sourceBlobContainer.ListBlobs().First();
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
Stream stream = blob.OpenRead(null, new BlobRequestOptions() { ServerTimeout = new System.TimeSpan(2, 59, 59), MaximumExecutionTime = new System.TimeSpan(2, 59, 59) });
response.Content = new StreamContent(stream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileNameZip;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
return response;
正如我所说,这段代码对于 20mb 的 mp4 文件运行良好,但对于 1Gb 或更大的 mp4 文件会引发异常。我得到的异常是:“异常:SocketException:现有连接被远程主机强制关闭”
如果我从请求代码中删除“await”并使用“.Result”,则会收到不同的异常:“异常:HttpRequestException:将内容复制到流时出错。”
单步执行代码,它输入“await client.PostAsync()”,我单步执行 Azure Web 服务代码,直到返回语句。然后我再一步,1-2分钟没有任何反应,然后抛出异常。
有人对可能发生的事情有任何想法吗?我认为这与流试图推送太多数据或某个地方超时有关,但我所做的一切似乎都无法解决问题。
最佳答案
由于 Azure Functions 的默认超时时间有限制,如下所示,因此您会遇到下载问题 Exception: SocketException: An Existing Connection was forcously Closed by the Remote Host
for download来自 Azure Functions 的大文件。请引用Functions limits .
因此,这些小文件可以在小于超时时间的短时间内下载完毕,但大文件将在超时后被强制关闭。
解决方案是从 Azure Function 向客户端响应带有 SAS token 的 blob url,然后直接通过 sas url 从 Azure Blob 存储下载 blob,因为 sas url 不需要额外的身份验证,并且 Azure 存储上没有超时限制。
如果您不熟悉如何为blob生成SAS token,可以引用官方示例代码Getting Started with Shared Access Signatures (SAS)
关于c# - 从 Azure 下载文件的 Web 服务会引发大文件异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56435024/