Home > Software design >  Reuse TCP connection in NSUrlSession
Reuse TCP connection in NSUrlSession

Time:08-14

I'm using NSURLSession to send https requests using method dataTaskWithRequest. Currently, In each call I create the session object from scratch in the following way :

NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
perationQueue.maxConcurrentOperationCount = 1;

NSURLSession* session = [NSURLSession 
            sessionWithConfiguration:configuration 
                            delegate:[challengeDelegate alloc] 
                       delegateQueue:operationQueue];

Than I use the this object with the send method :

NSMutableURLRequest *ns_req = [NSMutableURLRequest requestWithURL:reqUrl];

NSURLSessionDataTask *_dataTask = 
    [session dataTaskWithRequest:ns_req 
               completionHandler:^(NSData * _Nullable data,
                                   NSURLResponse * _Nullable response,
                                   NSError * _Nullable error) {...}

New server requirements that all requests are to be sent on the same tcp connection, So I wonder if it can be done by creating session only once (I keep it as class member) ?

But what happens the server will reset the connection (in case of timeout between 2 consecutive call or any other reason). How can I get indication for this event. Should I just set my session variable with a new NSURLSession object in order to refresh the object with new connection ?

CodePudding user response:

Q: So I wonder if it can be done by creating session only once (I keep it as class member) ?

A: It's not only can be done, but creating one session for multiple tasks is actually a proper way to use NSURLSession / URLSession. Here's what Apple says:

Your app creates one or more NSURLSession instances, each of which coordinates a group of related data-transfer tasks.

Q: But what happens the server will reset the connection (in case of timeout between 2 consecutive call or any other reason)

A: Generally speaking this is not your concern: NSURLSession operates on HTTP level, and management of the lower-level TCP connections is its internal job, which you can't affect much (except for few flags that NSURLSessionConfiguration has). And it can create and renegotiate a new connection, when needed.

But of course, if connection was closed while some dataTask is in progress, you will need to handle a corresponding error. The errors are of type URLError, and you can handle specific errors the way you want.

Q: Should I just set my session variable with a new NSURLSession object in order to refresh the object with new connection ?

A: NSURLSession instance is not the same as a single TCP connection. The NSURLSession has a normal lifecycle of any object - it will exist while there's at least one strong reference to it. So you need to make sure you keep your NSURLSession object reference so, that it can be reused (e.g. as an instance property of the class, not just local variable in the function that creates dataTask).

Side note:

New server requirements that all requests are to be sent on the same tcp connection

Although above method allows you to take advantage of optimization the Foundation will provide for TCP connections, it won't guarantee that the same connection is always used. The connection may drop (and new one will be automatically established), or user may move from one Wifi access point to another (which also requires a new connection).

If you need a full control over TCP connections, you won't be able to use NSURLSession and dataTask at all, you'd need to go to TCP level, and use sockets to communicate with your server.

  • Related