c# - 从 Azure 下载文件的 Web 服务会引发大文件异常

标签 c# azure azure-functions

我正在开发 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 .

enter image description here

因此,这些小文件可以在小于超时时间的短时间内下载完毕,但大文件将在超时后被强制关闭。

解决方案是从 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/

相关文章:

javascript - DateTimePicker js文件在azure中受到惩罚后不起作用

azure - Bizspark,将azure vm转移到另一个帐户

azure - 引用摘要验证失败

azure - 使用 Azure Functions 中的云应用设置

c# - 使用 XmlDocument 从带有或不带有命名空间的 xml 文件中读取

c# - 在 C# Outlook VSTO 中,有没有办法将用户 View 更改为日历 View 并突出显示特定日期?

c# - ASP.NET 核心 DI : Resolve same instance if scoped service is registered both as service type and implementation type

Azure - 从数据库动态获取计划并触发多种方法在azure中执行不同的任务?

c# - 正则表达式在 C# Azure 函数中包含一个(小写、大写、数字、给定的特殊字符)

c# - 在浏览器上输入 url 时出现设备未就绪错误