我正在尝试使用最新的(v2.2.2) AWS SDK将视频文件上传到S3。它在WiFi上运行得很好,但由于某种不知道的原因,每次在同一地点使用3G时都会出现故障。查看详细的调试输出,似乎每次都得到5个块,这似乎奇怪地一致。
我的上传代码是:
let credentialsProvider = CustomAmazonCredentialsProvider(accessKey: json["credentials"]["key"].stringValue, secretKey: json["credentials"]["secret"].stringValue, sessionKey: json["credentials"]["token"].stringValue)
let configuration : AWSServiceConfiguration = AWSServiceConfiguration(region: AWSRegionType.EUWest1, credentialsProvider: credentialsProvider)
configuration.maxRetryCount = 10;
AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
let filePath : String! = json["file_path"].stringValue
AWSS3.registerS3WithConfiguration(configuration, forKey: filePath)
AWSS3TransferManager.registerS3TransferManagerWithConfiguration(configuration, forKey: filePath)
let uploadRequest : AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()
let file : String = json["file_path"].stringValue
uploadRequest.body = NSURL(fileURLWithPath: self.videoPath!) //self.moviePlayer!.contentURL
uploadRequest.key = file
uploadRequest.bucket = json["bucket"].stringValue
self.uploadRequests.append(uploadRequest)
self.transferManager = AWSS3TransferManager.S3TransferManagerForKey(json["file_path"].stringValue)
uploadRequest.uploadProgress = {[unowned self](bytesSent:Int64,
totalBytesSent:Int64, totalBytesExpectedToSend:Int64) in
dispatch_sync(dispatch_get_main_queue(), { () -> Void in
var progress : CGFloat = CGFloat(totalBytesSent) / CGFloat(totalBytesExpectedToSend)
println("prog (progress)")
println("total (totalBytesSent)")
println("total (totalBytesExpectedToSend)")
if ( progress < 1.0 ) {
SVProgressHUD.showProgress(Float((CGFloat(totalBytesSent) / CGFloat(totalBytesExpectedToSend))), status: "Uploading", maskType: SVProgressHUDMaskType.None)
}
})
}
self.transferManager!.upload(uploadRequest).continueWithBlock({ (task) -> AnyObject! in
...
})
我很确定我有参考的一切,就像我说的,它在WiFi上工作得很好,所以为什么它会在移动网络上连续5块失败?
更新:下面是一些调试输出:
2015-07-29 10:34:55.938 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:653 | -[AWSS3ChunkedEncodingInputStream nextChunk] | stream read: 32677, chunk size: 32768
2015-07-29 10:34:55.947 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:669 | -[AWSS3ChunkedEncodingInputStream getSignedChunk:] | AWS4 String to Sign: [AWS4-HMAC-SHA256-PAYLOAD
20150729T093445Z
20150729/eu-west-1/s3/aws4_request
b1553d25ed783a533cd12380d9df4354f6d331d646692d4401b802cc30348502
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
70d7035aabde0212f688146957761f57dc68cab99dddb31ec0878aea6d222292]
prog 0.0495226365596895
total 98031
total 1979519
2015-07-29 10:34:55.951 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:675 | -[AWSS3ChunkedEncodingInputStream getSignedChunk:] | AWS4 Chunked Header: [007fa5;chunk-signature=4dc07dfbf557576f4a3fcb0bd976a0a24a4202e8bc19605b65447d5ac5839909
]
2015-07-29 10:34:55.952 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:653 | -[AWSS3ChunkedEncodingInputStream nextChunk] | stream read: 32677, chunk size: 32768
prog 0.066030182079586
total 130708
total 1979519
2015-07-29 10:35:01.379 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:669 | -[AWSS3ChunkedEncodingInputStream getSignedChunk:] | AWS4 String to Sign: [AWS4-HMAC-SHA256-PAYLOAD
20150729T093445Z
20150729/eu-west-1/s3/aws4_request
4dc07dfbf557576f4a3fcb0bd976a0a24a4202e8bc19605b65447d5ac5839909
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
c90c101be69ea0bac00649e48734dc4b23c3aa81a914d71961f810a1d98fc640]
2015-07-29 10:35:01.381 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:675 | -[AWSS3ChunkedEncodingInputStream getSignedChunk:] | AWS4 Chunked Header: [007fa5;chunk-signature=ecae7e66fbd9337aaf1063be3f8818293255ddc161e89c3fda929aecedb5d4f7
]
2015-07-29 10:35:01.382 Constent[6229:586874] AWSiOSSDKv2 [Debug] AWSSignature.m line:653 | -[AWSS3ChunkedEncodingInputStream nextChunk] | stream read: 32677, chunk size: 32768
prog 0.0825377275994825
total 163385
total 1979519
我还是不明白为什么它能如此可靠地粘在5 x 32k块上
可能发生了一些并发性问题。因为您将dispatch_sync
用于dispatch_get_main_queue()
,如果在块内阻塞了任何东西,则管理网络委托调用的队列可能会死锁。你应该确保在block中没有任何东西阻塞。另外,我将把dispatch_sync
改为dispatch_async
。
另外,您应该仔细检查CustomAmazonCredentialsProvider
的实现。AWS临时凭据确实会过期,当它过期时,您的凭据提供程序应该响应- refresh
,以便SDK可以检索一组新的凭据。通过符合AWSCredentialsProvider
来实现您的凭据提供程序。以AWSWebIdentityCredentialsProvider
和AWSCognitoCredentialsProvider
的实现为例。这个凭据提供程序应该:
- 检索
access key
,secret key
和session key
从您的服务器。 - 在本地持久化它们,直到它们过期。
- 在被请求时返回凭据。
- 如果过期,重新从服务器上检索它们。
- 在
- refresh
被调用时启动凭据刷新进程。
我鼓励你看看Amazon Cognito Identity。使用Amazon Cognito,您可以通过使用公共登录提供商(如Amazon、Facebook、Google和任何OpenID Connect兼容的提供商)或使用您自己的用户身份系统,为访问AWS云服务创建唯一的最终用户标识符。它涵盖了许多TVM用例,并且更易于使用和管理。