Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.96/25: Рейтинг темы: голосов - 25, средняя оценка - 4.96
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
1
.NET 4.x

HttpClient не работает Keep-Alive

21.10.2016, 10:29. Показов 4713. Ответов 17
Метки нет (Все метки)

Всем привет.
Для запросов использую следующий метод:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            using (var client = new HttpClient())
            {
                var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(request));
 
                var result = await client.SendAsync(requestMessage);
 
                if (result.IsSuccessStatusCode)
                {
                    return await ReadContentAsString(result);
                }
                else
                {
                    return string.Empty;
                }
            }
Весь msdn забит инфой, что по дефолту Keep-Alive = true в HTTP/1.1, но Fiddler показывает, что в заголовках Connection: Keep-Alive отсутствует. Перепробовал уже кучу способов пропихнуть этот заголовок, но всё четно... Помогите, может кто сталкивался.

Assembly System.Net.Http, Version=2.2.29.0
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.10.2016, 10:29
Ответы с готовыми решениями:

wiznet vs keep alive, как это работает???
Здравствуйте, заранее извиняюсь если тема не в той ветке или уже обсуждалась. ( но я никак не могу...

Не работает HttpClient
Первый раз пробую отправить и получить данные на сервер... Полазил в нете и накопал такую...

keep-alive в Qt
Нарыл код простейшего однопоточного http-сервера. main: #include <QCoreApplication> #include...

It is alive!
Как?! Как это может быть?! #include <iostream> int main () { int i = 4; char c = i; ...

17
968 / 863 / 349
Регистрация: 26.04.2012
Сообщений: 2,648
21.10.2016, 10:46 2
awp-sirius, ну а что мешает его добавить самым обычным образом?
C#
1
client.DefaultRequestHeaders.TryAddWithoutValidation("хедер", "значение");
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 10:52  [ТС] 3
EvilFromHell, Пробовал, не помогает.
Причём странный момент. Указываю:
C#
1
2
                client.DefaultRequestHeaders.Add("Connection", new string[] { "Keep-Alive" });
                client.DefaultRequestHeaders.Add("Keep-Alive", "600");
А в запросе Keep-Alive - 600 есть, но Connection пусто

И в сам реквест пытался прописывать
requestMessage.Headers.Add("Connection", "Keep-Alive"); - тоже не работает
0
968 / 863 / 349
Регистрация: 26.04.2012
Сообщений: 2,648
21.10.2016, 10:55 4
awp-sirius, а зачем там массив?

Добавлено через 1 минуту
И вообще, вы точно уверены, что этот хедер вам реально необходим? Если что, понять, какой хедер нужен, а какой не очень, легко через Fiddler. Там можно на вкладке Composer слать запросы, меняя хедеры, что позволяет быстро отследить, что необходимо, а что нет.
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 11:02  [ТС] 5
EvilFromHell, да это один из кучи вариантов, которые я пробовал))
("Connection", "Keep-Alive") тоже не работает

Добавлено через 6 минут
Кроме HttpClient я ещё использую простой HttpWebRequest (но он не асинхронный...)
Там у меня была такая же проблема. Мне её удалось решить лишь одним способом:
C#
1
2
3
                var sp = req.ServicePoint;
                var prop = sp.GetType().GetProperty("HttpBehaviour", BindingFlags.Instance | BindingFlags.NonPublic);
                prop.SetValue(sp, (byte)0, null);
0
968 / 863 / 349
Регистрация: 26.04.2012
Сообщений: 2,648
21.10.2016, 11:07 6
awp-sirius, у меня лично вообще этот хедер спокойно проставляется автоматически. А если я добавлю указанными выше способом-все спокойно добавляется, только дубль получается. Я не представляю, что можно сделать, чтобы этого не произошло. Да, и почему вы тогда уж не используете метод GetAsync?
0
Эксперт .NETАвтор FAQ
9856 / 4810 / 1731
Регистрация: 11.01.2015
Сообщений: 5,993
Записей в блоге: 34
21.10.2016, 11:14 7
Цитата Сообщение от awp-sirius Посмотреть сообщение
А в запросе Keep-Alive - 600 есть, но Connection пусто
Connection - это отдельное свойство.
Заносите значение нужно так:
C#
1
client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 11:22  [ТС] 8
Storm23, Когда прочитал обрадовался, думал поможет, но нет......

EvilFromHell, GetAsync в HttpWebRequest'e?
0
968 / 863 / 349
Регистрация: 26.04.2012
Сообщений: 2,648
21.10.2016, 11:25 9
awp-sirius, зачем вам вообще HttpWebRequest, если вы уже используете HttpClient, который гораздо удобнее? Я про HttpClient.

Добавлено через 1 минуту
awp-sirius, есть у меня подозрение, что вы как-то криво смотрите параметры запроса. Не вижу никаких причин не работать ни для моего варианта, ни для варианта Storm23.
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 11:34  [ТС] 10
EvilFromHell, Просто в проекте изначально использовался HttpWebRequest, постепенно переезжаю на HttpClient. По поводу запросов: смотрю в Fiddler там сложно смотреть как-то криво.

Сейчас ещё гляну что https://httpbin.org/headers вернёт

Добавлено через 3 минуты
вернулось только это:

JSON
1
2
3
4
5
6
{
  "headers": {
    "Accept-Encoding": "gzip", 
    "Host": "httpbin.org"
  }
}
с client.DefaultRequestHeaders.Connection.Add("Keep-Alive");
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 14:42  [ТС] 11
Всё ещё актуально.... Оказывается первый запрос отправляется с keep-alive, но потом почему-то соединение не поддерживается =(
Набросал консольку, на сайте сделал вывод хедеров. вот что получаю:
HttpClient не работает Keep-Alive
0
1449 / 842 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
21.10.2016, 16:27 12
Цитата Сообщение от awp-sirius Посмотреть сообщение
но потом почему-то соединение не поддерживается
Так! Вот теперь мне стало интересно для чего всё это!!!!! Какая задача?
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 16:36  [ТС] 13
LeniumSoft, Как для чего? Что бы каждый раз не поднималось новое соединение.
Но я вроде понял в чём проблема.
using (var client = new HttpClient()) каждый раз создаёт всё по новому и диспозит.
Если я выполняю несколько запросов именно внутри конкретного юзинга, то соединение поддерживается.
0
1449 / 842 / 150
Регистрация: 06.06.2012
Сообщений: 2,370
21.10.2016, 16:43 14
Цитата Сообщение от awp-sirius Посмотреть сообщение
Что бы каждый раз не поднималось новое соединение.
Показалось что задача из области SignalR
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
21.10.2016, 16:59  [ТС] 15
LeniumSoft, не, может немного не так выразился, да и в теории я не ас.
Соединение на стороне сервера.

В общем думаю теперь создавать хендлеры в конструкторах, откуда идут вызовы, и передавать их в метод получения данных
C#
1
using (var client = new HttpClient(handler, false))
0
Master of Orion
Эксперт .NET
6080 / 4936 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.10.2016, 11:35 16
awp-sirius, переписывать дословно с webrequest'ов на httpclient никакого смысла нет, внутри он все равно их использует. А имеет смысл, когда понятна идеология клиента (например, что это зачастую синглтон, который создается один раз за жизнь класса, а не создается на каждый запрос по-отдельности, как WebRequest'ы). То есть стоит поизучать, что он вообще умеет (поддержка кукисов/заголовков/всего остального). Собственно вы нашли способ поддержки - через хэндлера.

Буквально вчера проверял работу клиента, все работало И кастомные range-заголовки, и куки логина.
0
64 / 63 / 42
Регистрация: 01.05.2012
Сообщений: 535
22.10.2016, 19:54  [ТС] 17
Проверялось на практике, в HttpWebRequest если выполняется один долгий запрос, и в это время из другого потока сделать другой запрос, то будет ожидаться выполнение первого. Нет там асинхронности =( Вот тут https://referencesource.microsoft.com/ можно глянуть.

А по поводу заголовков - да, проблема была просто в том, что диспозился клиент. Но тут тоже у него внутри что-то не правильно отрабатывает.
Для меня стало открытием (не знаю как это работает на более глубоком уровне): оказывается заголовок keep-alive отправляется только 1 раз, в следующих запросах оно уже не шлётся.
Возможно это сделано специально, что бы уменьшить размер пакетов. Просто в системе кэшится домен и запоминает что туда этот заголовок уже был отправлен, но это лишь предположение.

Так вот собственно про эту проблему в httpclient. Если он диспозится и разрывает соединение, почему-то он не шлёт keep-alive во все пакеты...
0
Master of Orion
Эксперт .NET
6080 / 4936 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
22.10.2016, 22:29 18
awp-sirius, блин, диспоз означает что всё, соединение закрыто и больше я с тобой разговаривать сервер не буду. Конечно на все эти заголовки ему пофиг, если слать keep-alive, потом рвать соединение, а потом удивляться, что сервер не сохраняет его Сам же разорвал только что диспозом.

Цитата Сообщение от awp-sirius Посмотреть сообщение
оказывается заголовок keep-alive отправляется только 1 раз, в следующих запросах оно уже не шлётся.
То есть все происходит согласно спецификации: https://tools.ietf.org/html/rfc7230#section-6.3
Цитата Сообщение от awp-sirius Посмотреть сообщение
Возможно это сделано специально, что бы уменьшить размер пакетов. Просто в системе кэшится домен и запоминает что туда этот заголовок уже был отправлен, но это лишь предположение.
keep-alive это заголовок для сервера, причем он может забить на него и рвать соединение когда захочет, никто его не ограничивает. Клиент только просит, но не может заставить.

Добавлено через 1 минуту
Цитата Сообщение от awp-sirius Посмотреть сообщение
Проверялось на практике, в HttpWebRequest если выполняется один долгий запрос, и в это время из другого потока сделать другой запрос, то будет ожидаться выполнение первого. Нет там асинхронности =( Вот тут https://referencesource.microsoft.com/ можно глянуть.
Это предложение вообще не понял. Если в 2 потока запустить два HttpWebRequest'а то они не работают или что? Потому что дословный перевод этого класса "Http веб запрос", один объект - один запрос. Соответственно "сделать другой запрос с этим же HttpWebRequest'ом в другом потоке" бессмысленный.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
22.10.2016, 22:29

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Stayin’ Alive
Долго думала, куда написать: в форум о здоровье или в форум о музыке... Решила всё-таки в здоровье...

HTTP GET-запрос и keep-alive
Есть HTTP keep-alive соединение. Через него надо сделать серию GET-запросов. Со стороны клиента это...

Keep-Alive соединение и Cookie
Доброго времени суток, товарищи программисты. Столкнулся с такой вот ситуацией: При попытке...

Httpclient example
покажите пожалуйста простой пример загрузки файла(любого) или инфы с инета с помощью httpclient ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.