user3293746
user3293746

Reputation:

AFNetworking concurrent Http requests

I need to download around 200 Files from an API. They are all only around 15KB. My current code looks likes this:

NSOperationQueue* opQueue = [[NSOperationQueue alloc]init];
[opQueue setMaxConcurrentOperationCount:8];

NSString* baseUrl = @"https://someapi.com/somejson.json?page=";

for(int n = 0; n <= numberOfPages; n++) {
    @autoreleasepool {

         NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%d", baseUrl, n]]cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20];


        AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
        operation.responseSerializer = [AFJSONResponseSerializer serializer];

        [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"Done");
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error");
        }];

        [opQueue addOperation:operation];

    }
};

While this is working fine, i am curious if there is a faster way to do this. It currently takes about 20 seconds to download the files. Since they are all that small, i guess what takes the most time is waiting for the server response. Is there a better way of queueing them, so all the connections are established at the "same" time, or is that just kind of a hardcap?

I already tried setting

[opQueue setMaxConcurrentOperationCount:8];

to all kinds of different values, as well as not setting it at all. But that doesn't seem to really improve the performance.

This is a Charles log for one of the connections. The other ones are pretty much the same, but i can post more if necessary.

URL https://<hidden>&page=0
Status  Complete
Response Code   200 OK
Protocol    HTTP/1.1
Method  GET
Kept Alive  No
Content-Type    application/json; charset=utf-8
Client Address  /127.0.0.1
Remote Address  <hidden>
Timing  
Request Start Time  24.02.15 09:49:58
Request End Time    24.02.15 09:49:58
Response Start Time 24.02.15 09:49:59
Response End Time   24.02.15 09:49:59
Duration    1.18 sec
DNS 1 ms
Connect 42 ms
SSL Handshake   127 ms
Request 0 ms
Response    1 ms
Latency 974 ms
Speed   8,36 KB/s
Response Speed  9.626,95 KB/s

Size    
Request Header  283 bytes
Response Header 552 bytes
Request -
Response    9,09 KB (9306 bytes)
Total   9,90 KB (10141 bytes)
Request Compression -
Response Compression    91,8% (gzip) 

Upvotes: 1

Views: 871

Answers (3)

kean
kean

Reputation: 1561

AFHTTPRequestOperation uses bare bone NSURLConnection. I doubt there is anything you can do to improve server response time from the client side. However, there is a lot to be done on a server side:

  1. Just pack the files in a single archive if it's possible.

  2. The attached response headers state that the server disabled support for persistent HTTP connections:

Kept Alive No

Enabling keep-alive might be the best thing you can do. Disabled persistent connections are even worse for https than for http:

Defeating HTTP/1.1’s default Keep-Alive behavior is a bad practice for regular HTTP connections but it’s far worse for HTTPS connections because the initial setup costs of a HTTPS connection are far higher than a regular HTTP connection. Not only does the browser pay the performance penalty of setting up a new TCP/IP connection, including the handshake and initial congestion window sizing, but the request’s progress is also penalized by the time required to complete the HTTPS handshake used to secure the connection.

  1. And the last thing is HTTP pipelining. Make sure to check whether your server supports it. Then enable it on your requests:

    NSMutableURLRequest *request = ...
    request.HTTPShouldUsePipelining = YES;
    

Upvotes: 0

Sumeet
Sumeet

Reputation: 1055

It looks like the latency is the major contributor to the duration taken up to get a response to the request. One possible reason could be use of Proxy network. Also note that its not just the latency there is time taken to Connect, SSL Handshake which are also contributing to the Duration 1.18 sec.

Upvotes: 2

Huy Le
Huy Le

Reputation: 2513

The better is not set [opQueue setMaxConcurrentOperationCount:8];

Actually, you have 8 process will start at a same time. If you don't set it, you will have more.

Upvotes: 0

Related Questions