В настоящее время я разрабатываю приложение, в котором нам нужен какой-то запрос, чтобы поразить наш сервер как можно скорее. Чтобы ускорить процесс запроса, мы должны устранить рукопожатие (как это требуется дополнительно) и иметь постоянное соединение.Keep Alive не работает должным образом на iOS
Приложение использует структуру Alamofire сделать все запрос на наш сервер и настройка заключается в следующем:
У нас есть менеджер сеанса настройки с настройками по умолчанию и заголовок HTTP.
lazy var sessionManager: Alamofire.SessionManager = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders
let manager = Alamofire.SessionManager(configuration: configuration)
return manager
}()
Менеджер сеансов является постоянным по всем запросам. Каждый запрос сделан, используя следующий код:
self.sessionManager.request(request.urlString, method: request.method, parameters: request.parameters)
.responseJSON { [weak self] response in
// Handle the response
}
request.urlString это адрес нашего сервера «http://ourserver.com/example»
request.method устанавливается на сообщение
request.parameters является словарь paramators
Запрос работает нормально и мы получаем действительный ответ. Проблема возникает из-за таймера keep alive, который устанавливается нашим сервером до 300 секунд. Устройство поддерживает соединение в течение максимум 30 секунд на Wi-Fi и почти мгновенно закрывает его по GSM.
Сервер отладки
Мы сделали некоторые отладки на нашем сервере и найдены следующие результаты
Тесты:
Тест 1:
- iPhone подключается к Интернет через WiFi
Тест 2:
- iPhone подключается к Интернету через 3G
Поведение:
- обоих случаях: приложение делает HTTP/1.1 запрос к веб-серверу с «Connection: keep-alive»; Сервер (сервер ip = 10.217.81.131) отвечает «Keep-Alive: timeout = 300, max = 99»
- Клиентская сторона (тест 1 - приложение через WiFi) отправляет TCP FIN на 30-й секунде, и соединение закрывается
- клиентской стороны (тест 2 - приложение через 3G) отправляет немедленно (ноль секунд) запрос на TCP FIN после того, как он принимает HTTP/1.1 OK сообщение из его первого HTTP POST
тест 1 журналы на сервере сторона:
В 23.101902 приложение делает HTTP/1.Запрос 1 POST на сервер с «Connection: Keep-Alive»
На 23.139422 сервер отвечает HTTP/1.1 200 OK с «Connection: Keep-Alive» и «тайм-аут = 300» (300 секунд)
Круглый-Trip-Time (RTT) сообщается как 333.82 мс (это подчеркивает предел погрешности мы имеем на следующие временные метки):
Приложение, однако, закрывает соединение за 30 секунд (прибл. с учетом вариаций интернет-транспорта - разница между отметками времени 54.200863 и 23.451979):
Испытание повторяется многократно прибл. Время 30 секунд будучи всегда контролируется
Теста 2 бревна на стороне сервера:
- запрос HTTP/1.1 POST из приложения:
- HTTP-КИ ответа сервера с донжоном -alive принимаются и установлена на уровне 300 секунд:
- RTT является на 859.849 мсек
приложение закрывается сразу же соединение, где сразу же является 21.197918 - 18.747780 = 2.450138 секунд
Испытания повторяются при переключении с Wi-Fi на 3G и обратно с теми же результатами записывается.
Клиент отладки
Использование WiFi
Первая попытка (соединение установлено)
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])
Вторая попытка (в течение 30 секунд, соединение все еще живы)
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])
Затем через 30 секунд соединение падает (FI)
Использование 3G
Первая попытка
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])
Затем соединение падает почти мгновенно.
Не могли бы вы также зарегистрировать заголовки, которые поступают в ваше приложение с сервера? Обратите внимание, что некоторые прокси могут изменять заголовки keep-alive. – Sulthan
Вы пытались использовать «Keep-Alive» вместо «keep-alive» в запросе клиента? Спецификация немного неоднозначна, но это может иметь значение. – dgatwood
@Sulthan Я добавил заголовки, которые приходят в приложение с сервера в конце вопроса, в разделе «Отладка клиента». Я вижу, что на тестах wifi keep live имеет как таймаут, так и max, а на тестах 3g это не так. Интересно, это нормальное поведение. – zirinisp