2013-01-22 36 views
25

Tôi đang viết một ứng dụng ASP.NET Web API yêu cầu tôi chấp nhận tệp tải lên và chuyển tiếp tệp đó đến một điểm cuối HTTP khác.WebAPI Yêu cầu hỗ trợ trực tuyến

Tôi lo ngại rằng nếu nhiều người dùng cố gắng tải lên tệp 100MB mỗi (đây là trường hợp sử dụng hợp lệ) thì ứng dụng của tôi sẽ có dung lượng bộ nhớ lớn và tùy thuộc vào số lượng yêu cầu lớn mà dấu chân này có thể phát triển lớn ứng dụng của tôi sẽ keel hơn và chết.

Lý tưởng nhất là tôi muốn bắt đầu phát trực tuyến tệp đến điểm cuối HTTP khác ngay sau khi máy chủ web bắt đầu nhận tệp để giảm đáng kể tải trên máy chủ.

Tôi chắc chắn quá trình này có tên nhưng tôi không biết - điều này đang làm cho việc tìm kiếm nó khá khó khăn.

Tôi đã thực hiện khá nhiều công việc với Response Streaming trong API Web nhưng tôi chưa bao giờ phải xem xét yêu cầu phát trực tiếp trước đó.

tốt nhất tôi có thể nói tôi cần phải làm việc ra làm thế nào để:

  • Bắt đầu xử lý các dòng trước khi nó đã hoàn tất tải lên.
  • Sử dụng HttpClient để truyền cùng một yêu cầu để truyền cùng một dữ liệu đến điểm cuối HTTP khác.

Có ai có thể cung cấp cho tôi một số gợi ý không?

+1

Bạn đã sử dụng MultipartStreamProvider nào để thực hiện điều này? Tôi đang đấu tranh để đạt được cùng một điều chính xác ... Bạn có thể chia sẻ mã điều khiển của bạn? – Bredstik

Trả lời

38

Đó là một câu hỏi thú vị. Tôi sẽ cố hết sức để đưa ra một số gợi ý chung.

Vài điều cần xem xét:

1) Web API của bộ đệm mặc định yêu cầu nên sợ hãi của bạn mà bộ nhớ có thể là đáng kể chắc chắn là hợp lý. Bạn có thể buộc Web API để làm việc với các yêu cầu trong một chế độ xem trực tiếp:

public class NoBufferPolicySelector : WebHostBufferPolicySelector 
    { 
     public override bool UseBufferedInputStream(object hostContext) 
     { 
      var context = hostContext as HttpContextBase; 

      if (context != null) 
      { 
      if (string.Equals(context.Request.RequestContext.RouteData.Values["controller"].ToString(), "uploading", StringComparison.InvariantCultureIgnoreCase)) 
       return false; 
      } 

      return true; 
     } 

     public override bool UseBufferedOutputStream(HttpResponseMessage response) 
     { 
      return base.UseBufferedOutputStream(response); 
     } 
    } 

Và sau đó thay thế các dịch vụ:

GlobalConfiguration.Configuration.Services.Replace(typeof(IHostBufferPolicySelector), new NoBufferPolicySelector()); 

Xin lưu ý rằng do sự khác biệt giữa WebHost và SelfHost vào thời điểm này, sự thay đổi đó chỉ có thể thực hiện trong WebHost. Nếu thiết bị đầu cuối của bạn được selfHosted, bạn sẽ phải thiết lập các chế độ truyền hình ảnh ở mức GlobalConfig:

//requests only 
selfHostConf.TransferMode = TransferMode.StreamedRequest; 
//responses only 
selfHostConf.TransferMode = TransferMode.StreamedResponse; 
//both 
selfHostConf.TransferMode = TransferMode.Streamed; 

Tôi đã viết blog về đối phó với các tập tin lớn trong Web API chi tiết hơn trước - http://www.strathweb.com/2012/09/dealing-with-large-files-in-asp-net-web-api/ vì vậy hy vọng bạn sẽ thấy rằng hữu ích.

2) Thứ hai, nếu bạn sử dụng HttpClient, trong .NET 4 nó đệm cơ sở yêu cầu theo mặc định, vì vậy bạn thực sự nên sử dụng .NEt 4.5.

Nếu bạn phải sử dụng .NET 4 bạn đã làm việc với HttWebRequest trực tiếp: - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowreadstreambuffering.aspx - http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.allowwritestreambuffering.aspx

3) Theo như đẩy dữ liệu cho khách hàng đó là chắc chắn có thể nếu bạn muốn làm điều đó, với PushStreamContent. Henrik có một bài giới thiệu ngắn ở đây - http://blogs.msdn.com/b/henrikn/archive/2012/04/23/using-cookies-with-asp-net-web-api.aspx (nó dựa trên Web API RC bit, do đó bạn có thể cần phải điều chỉnh một số chữ ký vv) Tôi cũng viết blog về đẩy khối dữ liệu dòng ở đây - http://www.strathweb.com/2013/01/asynchronously-streaming-video-with-asp-net-web-api/

EDIT: Để xem ví dụ nếu PushStreamContent trong yêu cầu, bạn có thể xem giải pháp mẫu này - http://aspnet.codeplex.com/SourceControl/changeset/view/bb167f0b0013#Samples/Net45/CS/WebApi/UploadXDocumentSample/ReadMe.txt

+0

Tôi không nhận ra mình có thể sử dụng PushStreamContent khi đưa ra yêu cầu. Tôi đã từng sử dụng chúng trong một phản ứng. May mắn thay chúng ta đang sử dụng .NET 4.5 - vậy điều đó có nghĩa là HttpClient không yêu cầu bộ đệm sau đó? –

+0

Có - HttpClient trong .NET 4.5 không yêu cầu bộ đệm theo mặc định. Trong .NET 4 nó (nghĩa là tải toàn bộ yêu cầu vào bộ nhớ, sau đó gửi). –

+0

Tôi đã thêm một tham chiếu mẫu khác vào phản hồi (PushStreamContent trong yêu cầu) –

Các vấn đề liên quan