title: Keep Alive not working properly on iOS
body: <p>I am currently developing an application where we need some request to hit our server ASAP. To speed up the request process we have to eliminate handshake (as it takes extra) and have a permanent connection.</p>
  
  <p>The application is using the Alamofire framework to make all request to our server and the setup is the following:</p>
  
  <p>We have a session manager set up with default configuration and http header.</p>
  
  <pre><code>lazy var sessionManager: Alamofire.SessionManager = {
      let configuration = URLSessionConfiguration.default
      configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
      let manager = Alamofire.SessionManager(configuration: configuration)
      return manager
  }()
  </code></pre>
  
  <p>The session manager is persistent across all requests. Each request is made using the following code:</p>
  
  <pre><code>self.sessionManager.request(request.urlString, method: request.method, parameters: request.parameters)
              .responseJSON { [weak self] response in
      // Handle the response
  }
  </code></pre>
  
  <p>request.urlString is the url of our server "<a href="http://ourserver.com/example" rel="noreferrer">http://ourserver.com/example</a>"</p>
  
  <p>request.method is set to post</p>
  
  <p>request.parameters is a dictionary of paramaters</p>
  
  <p>The request is working fine and we get a valid response. <strong>The problem arises on the keep alive timer, which is set by our server to 300 seconds. The device holds the connection for a maximum of 30 seconds on wifi and closes it almost instantly over GSM.</strong></p>
  
  <hr>
  
  <p><strong>Server Debug</strong></p>
  
  <p>We did some debugging on our server and found the following results</p>
  
  <p>Tests:</p>
  
  <p>Test 1: </p>
  
  <ul>
  <li>iPhone connects to the Internet via WiFi</li>
  </ul>
  
  <p>Test 2:</p>
  
  <ul>
  <li>iPhone connects to the Internet via 3G</li>
  </ul>
  
  <p>Behaviour:</p>
  
  <ul>
  <li>Both cases: app makes an HTTP/1.1 request to a web server with “Connection: keep-alive”; The Server (server ip = 10.217.81.131) responds with “Keep-Alive: timeout=300, max=99” </li>
  <li>The client side (test 1 - app over WiFi) sends TCP FIN on the 30th second and the connection closes</li>
  <li>The client side (test 2 – app over 3G) sends immediately (zero seconds) a TCP FIN request after it receives the HTTP/1.1 OK message from its first HTTP POST </li>
  </ul>
  
  <p>Test 1 logs on the server side:</p>
  
  <ol>
  <li><p>At 23.101902 the app makes an HTTP/1.1 POST request to the server with “Connection: keep-alive”
  <a href="https://i.stack.imgur.com/QNDGF.png" rel="noreferrer"><img src="https://i.stack.imgur.com/QNDGF.png" alt="enter image description here"></a></p></li>
  <li><p>At 23.139422 the server responds HTTP/1.1 200 OK with “Connection: Keep-Alive” and “timeout=300” (300 seconds)
  <a href="https://i.stack.imgur.com/idVLs.png" rel="noreferrer"><img src="https://i.stack.imgur.com/idVLs.png" alt="enter image description here"></a></p></li>
  <li><p>The Round-Trip-Time (RTT) is reported as 333.82 msec (this highlights the margin of error we have on the following timestamps):</p></li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/mm4lF.png" rel="noreferrer"><img src="https://i.stack.imgur.com/mm4lF.png" alt="enter image description here"></a></p>
  
  <ol start="4">
  <li><p>The app, however, closes the connection in 30 seconds (approx. given the Internet transport variations – the difference between the 54.200863 and the 23.451979 timestamps):
  <a href="https://i.stack.imgur.com/iT2Q5.png" rel="noreferrer"><img src="https://i.stack.imgur.com/iT2Q5.png" alt="enter image description here"></a> </p></li>
  <li><p>The test is repeated numerous times with an approx. time of 30 seconds being always monitored</p></li>
  </ol>
  
  <p>Test 2 logs on the server side:</p>
  
  <ol>
  <li>The HTTP/1.1 POST request from the app: 
  <a href="https://i.stack.imgur.com/HhDxI.png" rel="noreferrer"><img src="https://i.stack.imgur.com/HhDxI.png" alt="enter image description here"></a></li>
  <li>The HTTP OK server response with keep-alive being accepted and set at 300 seconds:
  <a href="https://i.stack.imgur.com/ATXCo.png" rel="noreferrer"><img src="https://i.stack.imgur.com/ATXCo.png" alt="enter image description here"></a></li>
  <li>The RTT is at 859.849 msec
  <a href="https://i.stack.imgur.com/Cl57w.png" rel="noreferrer"><img src="https://i.stack.imgur.com/Cl57w.png" alt="enter image description here"></a></li>
  </ol>
  
  <p>The app closes immediately the connection, where immediately is 21.197918 – 18.747780 = 2.450138 seconds</p>
  
  <p>The tests are repeated while switching from WiFi to 3G and back with the same results being recorded.</p>
  
  <p><strong>Client Debug</strong></p>
  
  <p><em>Using WiFi</em></p>
  
  <p><em>First Attempt (connection established)</em></p>
  
  <pre><code>Optional(
  [AnyHashable("Content-Type"): text/html,
  
  AnyHashable("Content-Encoding"): gzip, 
  
  AnyHashable("Content-Length"): 36, 
  
  AnyHashable("Set-Cookie"): user_cookieuser_session=HXQuslXgivCRKd%2BJ6bkg5D%2B0pWhCAWkUPedUEGyZQ8%2Fl65UeFcsgebkF4tqZQYzVgp2gWgAQ3DwJA5dbXUCz4%2FnxIhUTVlTShIsUMeeK6Ej8YMlB11DAewHmkp%2Bd3Nr7hJFFQlld%2BD8Q2M46OMRGJ7joOzmvH3tXgQtRqR9gS2K1IpsdGupJ3DZ1AWBP5HwS41yqZraYsBtRrFnpGgK0CH9JrnsHhRmYpD40NmlZQ6DWtDt%2B8p6eg9jF0xE6k0Es4Q%2FNiAx9S9PkhII7CKPuBYfFi1Ijd7ILaCH5TXV3vipz0TmlADktC1OARPTYSwygN2r6bEsX15Un5WUhc2caCeuXnmd6xy8sbjVUDn72KELWzdmDTl6p5fRapHzFEfGEEg2LOEuwybmf2Nt6DHB6o6EA5vfJovh2obpp4HkIeAQ%3D; expires=Sun, 08-Jan-2017 12:51:43 GMT; path=/,
  
  AnyHashable("Keep-Alive"): timeout=300, max=100, 
  
  AnyHashable("Connection"): Keep-Alive, 
  
  AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11, 
  
  AnyHashable("Server"): Apache/2.2.22 (Ubuntu), 
  
  AnyHashable("Vary"): Accept-Encoding, 
  
  AnyHashable("Date"): Sun, 08 Jan 2017 10:51:43 GMT])
  </code></pre>
  
  <p><em>Second Attempt (within 30 sec, the connection is still alive)</em></p>
  
  <pre><code>Optional([AnyHashable("Content-Type"): text/html, 
  
  AnyHashable("Content-Encoding"): gzip, 
  
  AnyHashable("Content-Length"): 36, 
  
  AnyHashable("Keep-Alive"): timeout=300, max=99, 
  
  AnyHashable("Connection"): Keep-Alive, 
  
  AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11, 
  
  AnyHashable("Server"): Apache/2.2.22 (Ubuntu), 
  
  AnyHashable("Vary"): Accept-Encoding, 
  
  AnyHashable("Date"): Sun, 08 Jan 2017 11:00:18 GMT])
  </code></pre>
  
  <p>Then after 30 seconds the connection drops (FI)</p>
  
  <p><em>Using 3G</em></p>
  
  <p><em>First Attempt</em></p>
  
  <pre><code>Optional([AnyHashable("Content-Type"): text/html, 
  
  AnyHashable("Content-Encoding"): gzip, 
  
  AnyHashable("Content-Length"): 36, 
  
  AnyHashable("Connection"): keep-alive, 
  
  AnyHashable("X-Powered-By"): PHP/5.3.10-1ubuntu3.11, 
  
  AnyHashable("Server"): Apache/2.2.22 (Ubuntu), 
  
  AnyHashable("Vary"): Accept-Encoding, 
  
  AnyHashable("Date"): Sun, 08 Jan 2017 11:04:31 GMT])
  </code></pre>
  
  <p>Then the connection drops almost instantly.</p>