Инетовские ф-ции WinInet Api
От: Bulky  
Дата: 02.07.01 08:05
Оценка:
Необходимо пересылать параллельно несколько разных сообщений через 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.

И как же вообще работает браузер, в таком случае?..
Re: Инетовские ф-ции WinInet Api
От: IT Россия linq2db.com
Дата: 02.07.01 13:29
Оценка:
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.

Олег
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.