NSURLSessionUploadTask (1) загружает данные, (2) зависает на ~200 с, (3) повторяется

Вот где я до сих пор с NSURLSessionUploadTask:

  • Приложение iOS запускает NSURLSessionUploadTask с помощью POST
  • сервер получает запрос HTTP POST
  • сервер считывает содержимое запроса, поэтому данные загружаются
  • Приложение iOS многократно вызывает URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:, заканчивая окончательным вызовом с totalBytesSent равным totalBytesExpectedToSend
  • сервер отправляет HTTP-ответ на iOS, состоящий из следующего:
HTTP/1.1 200 OK
Server: BaseHTTP/0.3 Python/2.7.10
Date: Fri, 30 Oct 2015 16:15:21 GMT
Content-Type: text/html

<html><head><title>POST RESPONSE</title></head><body><p>The file was uploaded.</p></body></html>
  • Приложение iOS получает этот ответ (подтверждено через Wireshark) Wireshark
  • iOS application does not call the following methods to complete the upload task like it supposed to:
    • NSURLSessionTaskDelegate: -> URLSession:dataTask:didReceiveData:
    • NSURLSessionTaskDelegate -> URLSession:task:didCompleteWithError:
  • вместо этого после зависания в течение ~ 200 секунд приложение iOS повторяет задачу загрузки данных

Эта загрузка данных, ответ HTTP 200, процесс зависания ~ 200 секунд, кажется, повторяется бесконечно. Почему NSURLSessionTaskDelegate: -> URLSession:dataTask:didReceiveData: и NSURLSessionTaskDelegate -> URLSession:task:didCompleteWithError: не вызываются после получения HTTP-ответа приложением iOS?


person drbobdugan    schedule 02.11.2015    source источник


Ответы (1)


После правильной загрузки данных через HTTP-запрос на сервер приложение iOS получило HTTP-ответ, но поскольку в HTTP-ответе не было передано Content-Length, приложение iOS не могло узнать, когда HTTP-ответ закончился. Два возможных решения:

  • сервер закрывает сокет после передачи ответа HTTP
  • Content-Length включен в ответ HTTP
HTTP/1.1 200 OK
Server: BaseHTTP/0.3 Python/2.7.10
Date: Fri, 30 Oct 2015 16:15:21 GMT
Content-Type: text/html
Content-Length: 96

<html><head><title>POST RESPONSE</title></head><body><p>The file was uploaded.</p></body></html>

I tried both solutions sucessfully, but the Content-Length solution is superior because it reduces network overhead by allowing iOS application and server (assuming the server supports keep-alive) to maintain the socket connection for future HTTP requests.

Я также разместил очень простой пример приложения NSURLSessionUploadTask и веб-сервера на github здесь.

person drbobdugan    schedule 02.11.2015