2012-02-28 32 views
7

My chưa được phát hành Ứng dụng Delphi 2010 cho phép người dùng tải tệp của họ lên máy chủ của tôi. Ngay bây giờ tôi đang sử dụng HTTPS POST để gửi các tập tin, các (giản thể) thuật toán về cơ bản là:Làm cách nào để tối ưu hóa quá trình tải lên thường xuyên bằng Delphi 2010?

  1. chia file thành "lát" (256KB mỗi)
  2. Đối với mỗi lát, gửi nó đến máy chủ

tức là. cho một tập tin 1MB:

--> Get Slice #1 (256KB) 
--> Upload Slice #1 using TidHTTP.Post() 

--> Get Slice #2 (256KB) 
--> Upload Slice #2 using TidHTTP.Post() 

--> Get Slice #3 (256KB) 
--> Upload Slice #3 using TidHTTP.Post() 

--> Get Slice #4 (256KB) 
--> Upload Slice #4 using TidHTTP.Post() 

Tôi đang sử dụng Indy 10. Tôi (ab) sử dụng profiler của tôi hơn và hơn và không có nhiều trái để tối ưu hóa ngoại trừ thay đổi thói quen tải lên chính nó.

Tôi cũng đang sử dụng đa luồng, và mặc dù tôi đã làm hết sức mình để tối ưu hóa mã của tôi, tiêu chuẩn của tôi vẫn cho tôi biết tôi có thể làm tốt hơn (có phần mềm tối ưu hóa tốt khác mà làm đạt được một nhiều ! thời gian tốt hơn ... gần gấp đôi nhanh như thường lệ upload của tôi)

tôi biết đó không phải lỗi máy chủ của tôi ... đây là những ý tưởng mà tôi vẫn cần phải khám phá:

  1. tôi đã cố gắng nhóm lát trong một POST duy nhất, tự nhiên điều này dẫn đến tăng hiệu suất (20-35%) nhưng khả năng tiếp tục được giảm xuống.

  2. Tôi cũng nghĩ đến việc sử dụng SFTP/SSH, nhưng tôi không chắc liệu nó có nhanh hay không.

  3. Sử dụng ổ cắm web để triển khai tải lên có thể tiếp tục lại (như this component), tôi cũng không chắc về tốc độ.

Bây giờ câu hỏi của tôi là: có điều gì tôi có thể làm để tăng tốc độ tải lên của mình không? Tôi mở cửa cho bất kỳ gợi ý rằng tôi có thể thực hiện, bao gồm các công cụ dòng lệnh (nếu giấy phép cho phép tôi gửi nó với ứng dụng của tôi), với điều kiện:

  1. upload thể tiếp tục lại được hỗ trợ
  2. nhanh!
  3. sử dụng bộ nhớ hợp lý
  4. an toàn & cho phép xác thực đăng nhập/user

Ngoài ra, vì lo ngại an ninh lớn, FTP là một không phải là điều tôi muốn thực hiện.

Cảm ơn rất nhiều!

+1

Chuyển khoản có sử dụng tính năng nén/giải nén dữ liệu không? – mjn

+0

những gì ở phía máy chủ? – kobik

+0

@mjn: yes (lát đã được nén trước khi được tải lên + Tôi sử dụng TIdCompressorZLib của Indy) – TheDude

Trả lời

5

Tôi sẽ đề xuất thực hiện một đơn TIdHTTP.Post() cho toàn bộ tệp mà không cần phải chunking nó cả. Bạn có thể sử dụng các sự kiện TIdHTTP.OnWork... để theo dõi số lượng byte đã được gửi tới máy chủ để bạn biết vị trí cần tiếp tục từ nếu cần. Khi tiếp tục, bạn có thể sử dụng thuộc tính TIdHTTP.Request.CustomHeaders để bao gồm tiêu đề tùy chỉnh cho máy chủ biết bạn đang tiếp tục từ đâu, vì vậy, nó có thể quay lại tệp trước đó thành bù đắp được xác định trước khi chấp nhận dữ liệu mới.

+0

Tuyệt vời, tôi không biết tôi có thể tiếp tục POST. Hãy để tôi xem nếu tôi có quyền này: trong mã PHP, tôi thêm này -> tiêu đề ('Chấp nhận-Ranges: byte'); và trong Delphi nếu tôi thêm này (chỉ là một ví dụ): IdHTTP.Request.CustomHeaders.Add ('Range: bytes = 5000-'); HTTP POST sẽ tự động loại bỏ các byte thừa (cuộn lại) và lấy từ byte thứ 5000, đúng không? – TheDude

+0

Để tiếp tục một 'POST' trước đó, bạn có thể chuyển vào một' TStream' chỉ có dữ liệu còn lại trong đó. Nhưng máy chủ phải hỗ trợ tiếp tục và nối dữ liệu mới vào tệp hiện có, không ghi đè lên tệp mới. Tải lên tiếp tục không phải là một phần của giao thức HTTP chuẩn. Tiêu đề phản hồi 'Accept-Ranges' và tiêu đề yêu cầu' Range' chỉ dành cho ** lượt tải xuống ** chứ không phải ** tải lên **. Khi tôi đề cập đến một tiêu đề tùy chỉnh, tôi đã đề cập đến một tiêu đề 'X -...' tùy chỉnh của thiết kế của riêng bạn mà mã PHP của bạn có thể tìm kiếm, ví dụ: 'X-Tiếp tục-Từ: ...'. –

+0

Hoặc tiêu đề 'Nội dung-Phạm vi', mặc dù RFC 2616 cho thấy rằng nó thường chỉ được sử dụng trong phản hồi, không phải trong yêu cầu. –

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