Необходимо пересылать параллельно несколько разных сообщений через HTTP на сервер.
На сервере работает ASP скрипт который обрабатывает поступающие сообщения и выдает ответ через произвольный промежуток времени. Промежуток может колебаться от нескольких секунд до минуты и более.
Клиент, который посылает сообщения выполнен в виде сервиса. Для пересылки я воспользовался интренетовскими ф-ями из набора WinInet API.
Для отправки каждого сообщения создается своя нить и в ней вызывается HTTPSendRequest.
Работа идет по след. схеме: InternetOpen/InternetConnect/HTTPOpenRequest
Потом в каждой нити: HTTPSendRequest/InternetReadFile (для чтения ответа)
Причем для каждого сообщения создается свое соединение ,т.е. каждый раз вызывается InternetConnect/HTTPOpenRequest
Главная проблема: Сообщения отсылаются на сервер последовательно. Т.е.Wininet.dll блокирует вызовы других нитей, если в данный момент уже обрабатывается запрос от какой-либо нити.
Таким образом, отсылается HTTPSendRequest, происходит возврат из него, далее вызывается InternetReadFile который подвисает т.к. ждет реакции от ASP (несколько секунд), но в это время также подвисают вызовы HTTPSendRequest от других нитей, пока не будет вызван InternetCloseHandle для первой нити.
Что можно сделать в данной ситуации? Может нужен др. подход? Все делать на более низком уровне (через tcp/ip) или может есть какие-либо библиотеки, в которых реализована более приятная поддрежка HTTP?
Необходимость использовать HTTP вызвана простой возможностью переключиться на использование SSL.
Была сделана попытка использовать асинхронные версии инетовских функций. Т.е. HTTPSendRequestEx, HTTPEndRequest и InternetQueryDataAvailable, плюс callback функция.
Соединение происходит успешно, но реакция сервера не читается как следует: иногда читается но не всё, иногда вообще вылетает исключение изнтури Wininet.dll.
И как же вообще работает браузер, в таком случае?..
B>Необходимо пересылать параллельно несколько разных сообщений через HTTP на сервер.
B>Клиент, который посылает сообщения выполнен в виде сервиса. Для пересылки я воспользовался интренетовскими ф-ями из набора WinInet API.
Под каким аккаунтом работает сервис?
B>Работа идет по след. схеме: InternetOpen/InternetConnect/HTTPOpenRequest B>Потом в каждой нити: HTTPSendRequest/InternetReadFile (для чтения ответа)
B>Причем для каждого сообщения создается свое соединение ,т.е. каждый раз вызывается InternetConnect/HTTPOpenRequest
Понятна...
B>Главная проблема: Сообщения отсылаются на сервер последовательно. Т.е.Wininet.dll блокирует вызовы других нитей, если в данный момент уже обрабатывается запрос от какой-либо нити.
Дакументированная фича :(
B>Таким образом, отсылается HTTPSendRequest, происходит возврат из него, далее вызывается InternetReadFile который подвисает т.к. ждет реакции от ASP (несколько секунд), но в это время также подвисают вызовы HTTPSendRequest от других нитей, пока не будет вызван InternetCloseHandle для первой нити.
Логично.
B>Что можно сделать в данной ситуации? Может нужен др. подход? Все делать на более низком уровне (через tcp/ip) или может есть какие-либо библиотеки, в которых реализована более приятная поддрежка HTTP?
Обойдёмся и wininet'ом.
B>Необходимость использовать HTTP вызвана простой возможностью переключиться на использование SSL.
Тоже правильно.
B>Была сделана попытка использовать асинхронные версии инетовских функций. Т.е. HTTPSendRequestEx, HTTPEndRequest и InternetQueryDataAvailable, плюс callback функция. B>Соединение происходит успешно, но реакция сервера не читается как следует: иногда читается но не всё, иногда вообще вылетает исключение изнтури Wininet.dll.
B>И как же вообще работает браузер, в таком случае?..
Этот вопрос я тоже себе задавал ;o)
Итак, по-порядку, я как раз только что отборолся с подобной задачей.
WinInet имеет несколько документированных недостатков.
1. Он не может работать под системным аккаунтом, странно что он у тебя работет в сервисе, не должен :). Скорее всего ты получишь отлуп если перейдёшь на SSL. Это связано с тем, что из-под системного аккаунты недоступны определённые части реестра, в том числе связанные с защитой.
2. WinInet не может обрабатывать одновременно больше двух коннекций. С помощью определйнных извратов это число можно удвоить, но это тоже не выход.
3. Нельзя одновременно использовать два запроса на одном соединении.
Как же тогда работает браузер?
Очень просто: он не работает под системным аккаунтом, он не использует больше двух соединений, он не запускает одновременно несколько запросов.
Выход я нашёл несколько кривоватый и дубовый как двери. Всю работу с WinInet я завернул в COM .EXE сервер и каждый раз при создании нового объекта создаётся копия отдельного процесса. Теперь WinInet у меня летает как трофейный мессершмидт. Только одна печаль — сердце кровью обливается, когда смотришь в TaskManager на то как создаются и убиваюься процессы. Зато всё работает быстро.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Инетовские ф-ции WinInet Api
От:
Аноним
Дата:
03.07.01 01:27
Оценка:
Здравствуйте Bulky, вы писали:
B>Необходимо пересылать параллельно несколько разных сообщений через HTTP на сервер. B>На сервере работает ASP скрипт который обрабатывает поступающие сообщения и выдает ответ через произвольный промежуток времени. Промежуток может колебаться от нескольких секунд до минуты и более.
B>Что можно сделать в данной ситуации? Может нужен др. подход? Все делать на более низком уровне (через tcp/ip) или может есть какие-либо библиотеки, в которых реализована более приятная поддрежка HTTP?
...
B>Необходимость использовать HTTP вызвана простой возможностью переключиться на использование SSL.
извините, не понял. по-моему проще и правильнее в данном случае работать через сокеты.
написать своего клиента для сервера, и шифровать свои данные, "как бог на душу...".
может тогда будет достаточно одного потока.
если нет — не беда. все прекрасно будет работать.
единственное ограничение, как у меня сейчас, в проекте разрешен единственный порт http.
ну тут уж — могу понять.
но я бы собрал все сообщения в один пакет и передал в один заход.
B>И как же вообще работает браузер, в таком случае?..
броузер в одном окне, в данный момент времени запрашивает(принимает) только один документ.
P.S. wininet — нормальная библиотека для быстрого написания. претензий нет.
но для работы пишу на winsock.