我正在编写一个Web应用程序和一个OS X应用程序,它将文件上传到服务器。
网络应用使用FlowJS来处理将文件发送到服务器。随着每个请求,它发送块号,块大小,总文件大小,文件名,等。这很好,因为在幕后我将这些数据上传到S3,我使用这个用于确定文件何时完成上载的信息。此外,由于数据是块状的,我不必将整个文件存储在我的服务器的内存中。
对于具有目标c的OS X,我打算使用AFNetworking。我尝试使用分段上传:
-(void)uploadFileWithUrl:(NSURL*)filePath {
AFHTTPRequestOperationManager*manager = [AFHTTPRequestOperationManager manager];
[manager POST:@"http://www.example.com/files/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileURL:filePath name:@"blob" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}
但这只是尝试在一个请求中发送整个文件,这是不可接受的,因为服务器在大量请求时将耗尽内存。
我想知道的是,对于目标C是否有类似FlowJS的内容,或者是否有某种方法可以将AFNetworking中的信息包含在每次调用中。
答案 0 :(得分:-1)
我认为你不能很容易地自动完成这项工作。 (如果有人知道如何做到这一点,我想知道答案。)
Multipart没有帮助,因为它构建内容,但不构成传输。将其视为文本文档中的段落:它们为文本提供结构,但它仍然是一个文件。
这会导致真正的问题:您希望拥有固定大小的块并在处理完一个块(上传到S3)后发送一个块,然后发送下一个块,依此类推。客户端如何知道第一个块被处理?当服务器收到第一个数据时,HTTP不能像您发送新数据那样工作。当发送第一个块时(在途中),您发送下一个块。我不确定AFNetworking是否保证在发送第一部分后请求下一部分...也许它想收集小部件。
为什么不做,S3确实:
使用ID作为响应发起上传请求。然后使用该上传ID发送一个块。如果完成,服务器响应并发送下一部分。这样做你就握手了。