Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

XMLHTTP   Найти похожие ветки 

 
dima_q   (2008-06-30 13:13) [0]

Здравствуйте Мастера!
Есть COM библиотека служащая для общения с сервером. Общения происходит посредством xml по http. Для непосредственной связи используется объект XMLHTTP. Вопрос: Для работы с сервером, в моей либе создается отдельный поток. В потоке осуществляется вход в апартмент:
CoInitializeEx(nil, COINIT_APARTMENTTHREADED). После создания объекта c и присвоения всех свойств, вызывается метод XMLHTTP.send(). Так вот при использовании потоковой модели STA(COINIT_APARTMENTTHREADED) запрос на сервер не идет, все остается висеть навечно. А при использовании MTA все благополучно проходит. Сам сервер XMLHTTP в реестре помечен как Appartment. Подскажите в чем может быть проблема. Почему при STA не вознивает никаких ошибок, но запрос не происходит? P.S.: использовать MTA нет возможности, из-за дальнейших проблем с клиентами моей либы.


 
Сергей М. ©   (2008-06-30 13:29) [1]

А при CoInitialize(nil) работает ?


 
dima_q   (2008-06-30 13:35) [2]


> Сергей М. ©   (30.06.08 13:29) [1]
> А при CoInitialize(nil) работает ?

Нет не работает. CoInitialize(nil) идентичен CoInitializeEx(nil, COINIT_APARTMENTTHREADED), это его сокращенный вызов.


 
dima_q   (2008-06-30 13:37) [3]

Вся проблема в том, что при работе с CoInitializeEx(nil, COINIT_APARTMENTTHREADED) нет никаких ошибок. Просто тупо не посылает запрос.


 
Сергей М. ©   (2008-06-30 16:37) [4]


>  тупо не посылает запрос.


С чего ты взял, что "не посылает" ?

А если и не посылает, то что значит "все .. висеть" ?

ты исключения обрабатываешь ?


 
dima_q   (2008-06-30 17:51) [5]

Исключения обрабатываю, их нет. Висит, в смысле на сервере, он тоже мой, стоит бряка, но запрос не доходит до него.


 
dima_q   (2008-06-30 17:53) [6]

И статус (XMLHTTP.readyStatus) не изменяется никогда, он всегда 1. Хотя сервер доступен.


 
clickmaker ©   (2008-06-30 17:59) [7]

onreadystatechange используешь или синхронно?


 
dima_q   (2008-06-30 18:09) [8]


> clickmaker ©   (30.06.08 17:59) [7]
> onreadystatechange используешь или синхронно?

Не использую. Просто в цикле проверяю XMLHTTP.readyState.


 
clickmaker ©   (2008-06-30 18:16) [9]

погодь... насколько я знаю, там либо синхронно, тогда send не вернет, пока не выполнится, либо асинхронно, тогда надо вешать onreadystatechange
попробуй второй вариант


 
dima_q   (2008-06-30 18:30) [10]

Пробовал при асинхронном запросе вешать onreadystatechange, не происходит события. Сейчас попробую, что скажет синхронный.


 
dima_q   (2008-06-30 19:27) [11]

В синхронном режиме сенд проходит нормально, не знаю что делать...


 
Сергей М. ©   (2008-06-30 19:47) [12]


> В синхронном режиме сенд проходит нормально


Отсюда и вывод: threading model тут совершенно ни причем.

Похоже что XMLHTTP в асинхр.режиме заточен на нотификацию посредством оконных сообщений. И, поскольку в теле цикла ты не предпринимаешь никаких телодвижений по выборке/диспетчеризации оных, ожидать onreadystatechange или изменение readyState придется до второго пришествия.


 
dima_q   (2008-07-01 09:35) [13]


> Сергей М. ©

Буду копать в сторону цикла обработки сообщений в потоке. Мот я просто не так добавлял его, попробую еще раз, огромное спасибо!


 
Сергей М. ©   (2008-07-01 16:47) [14]


> Мот я просто не так добавлял его


Кого ?!


 
dima_q   (2008-07-02 09:42) [15]


> Кого ?!

Цикл обработки сообщений. Попробовал, не работает все равно. Незнаю, что делать:(


 
Сергей М. ©   (2008-07-02 10:16) [16]


> Незнаю, что делать


Ну как что ?
Трясти бубен, если код своего цикла показывать не желаешь)


 
dima_q   (2008-07-02 10:26) [17]


> Трясти бубен, если код своего цикла показывать не желаешь)

 Думаю бубен вряд ли поможет, а код,  вот он:

   TXMLHTTPThread = class(TThread)
   private
       m_xmlHTTP30 : MSXML3.TXMLHTTP30;
       m_xmlHTTP40 : MSXML5.TXMLHTTP40;
       m_xmlHTTP50 : MSXML5.TXMLHTTP50;
     ...

       procedure ParseResponse();
       function  CheckOfTimeout(xmlHTTP : TXMLHTTP) : integer;// 0 - aborted, 1 - timed out, 4 - successful;
   public
       AlwaysSaveToFile : boolean;
       constructor Create(async : boolean; url: string; sFileName: string = ""; stmPost: TIdMultipartFormDataStream = nil);
       destructor Destroy(); override;
       procedure Execute(); override;
       ...
   end;

...
   function TXMLHTTPThread.CheckOfTimeout(xmlHTTP: TXMLHTTP): integer;
   var lastState, diff : integer;
       ticks : cardinal;
       rMsg : TMsg;
   const ts : array [0..3] of integer = (60*1000,60*1000,10*60*1000,10*60*1000);
   begin
       Result := 4;
       ticks := GetTickCount();
       lastState := xmlHTTP.readyState;
       while (lastState <> 4) do
       begin
           while (GetMessage (rMsg,0,0,0)) do DispatchMessage (rMsg);
           Sleep(50);
           if (GetTickCount() - ticks > ts[lastState]) then
           begin
               xmlHTTP.abort();
               Result := 1;
               Exit;
           end;
           if Terminated then
           begin
               xmlHTTP.abort();
               Result := 0;
               Exit;
           end;
           if (xmlHTTP.readyState > lastState) then
           begin
              ticks := GetTickCount();
              lastState := xmlHTTP.readyState;
           end;
       end;
   end;

   constructor TXMLHTTPThread.Create(async : boolean; url: string; sFileName: string = ""; stmPost: TIdMultipartFormDataStream = nil);
   begin
       inherited Create(true);
       m_xmlHTTP30 := nil;
       m_xmlHTTP40 := nil;
       m_xmlHTTP50 := nil;
       ...
   end;

   destructor TXMLHTTPThread.Destroy();
   begin
      ...
   end;

   procedure TXMLHTTPThread.Execute();
   var stmString : TStringStream;
       i, rs : integer;
       s : string;
   begin
       CoInitializeEx(nil, COINIT_APARTMENTTHREADED);
       //COINIT_MULTITHREADED
       //COINIT_APARTMENTTHREADED

       case (XMLVersion) of
           xml30: m_xmlHTTP30 := MSXML3.TXMLHTTP30.Create(nil);
           xml40: m_xmlHTTP40 := MSXML5.TXMLHTTP40.Create(nil);
           xml50: m_xmlHTTP50 := MSXML5.TXMLHTTP50.Create(nil);
           xmlUnknown :
           begin
               m_error := "Cannot access network : MSXML version 3.0 or higher is required";
               m_completed := true;
               CoUninitialize();
           end;
       end;

       try
           try
               ...

               if (XMLVersion = xml30) then
               begin
                   if (m_stmPost <> nil) then m_xmlHTTP30.send(m_postdata)
                   else m_xmlHTTP30.send();
                   if m_async then
                       case CheckOfTimeout(TXMLHTTP(m_xmlHTTP30)) of
                           0: begin m_error := "aborted"; Exit; end;
                           1: begin m_error := "timed out"; Exit; end;
                       end;
               end else if (XMLVersion = xml40) then
               begin
                   if (m_stmPost <> nil) then m_xmlHTTP40.send(m_postdata)
                   else m_xmlHTTP40.send();
                   if m_async then
                   begin
                       case CheckOfTimeout(TXMLHTTP(m_xmlHTTP40)) of
                           0: begin m_error := "aborted"; Exit; end;
                           1: begin m_error := "timed out"; Exit; end;
                       end;
                   end;
               end else
               begin
                   if (m_stmPost <> nil) then m_xmlHTTP50.send(m_postdata)
                   else m_xmlHTTP50.send();
                   if m_async then
                   begin
                       case CheckOfTimeout(TXMLHTTP(m_xmlHTTP50)) of
                           0: begin m_error := "aborted"; Exit; end;
                           1: begin m_error := "timed out"; Exit; end;
                       end;
                   end;
               end;

               if (XMLVersion = xml30) then
                   rs := m_xmlHTTP30.readyState
               else if (XMLVersion = xml40) then
                   rs := m_xmlHTTP40.readyState
               else
                   rs := m_xmlHTTP50.readyState;

               if (rs >= 2) then // LOADED, STATUS is available
               begin
                   if (XMLVersion = xml30) then
                       m_respCode := m_xmlHTTP30.status
                   else if (XMLVersion = xml40) then
                       m_respCode := m_xmlHTTP40.status
                   else
                       m_respCode := m_xmlHTTP50.status;
                   try
                       if (m_respCode >= 400) then
                       begin
                           m_error := "ServerXMLHTTP returned an error : ";
                           if (XMLVersion = xml30) then
                               s := m_xmlHTTP30.statusText
                           else if (XMLVersion = xml40) then
                               s := m_xmlHTTP40.statusText
                           else
                               s := m_xmlHTTP50.statusText;

                           if (Length(s) > 0) then m_error := m_error + s
                           else m_error := m_error + ResponseCodeText(m_respCode);
                       end;
                   except end;
               end;

               if (rs = 4) then ParseResponse();

           except
               on ex : Exception do
               begin
                   m_error := {"ServerXMLHTTP has returned an error: " +} ex.Message;
               end;
           end;
       finally
           m_completed := true;
           if (XMLVersion = xml30) then
               FreeAndNil(m_xmlHTTP30)
           else if (XMLVersion = xml40) then
               FreeAndNil(m_xmlHTTP40)
           else
               FreeAndNil(m_xmlHTTP50);
           CoUninitialize();
       end;
   end;
end.


 
Сергей М. ©   (2008-07-02 11:27) [18]

Чудесно.

А где в этом коде собственно установка асинхронного режима работы компонента ?

Или это дифолтный режим ?


 
dima_q   (2008-07-02 11:41) [19]


> А где в этом коде собственно установка асинхронного режима
> работы компонента ?

Нет не дефолтный. Он передается параметром в функцию Open:
m_xmlHTTP50.open("POST", m_url, m_async);
я просто удалил куски кода(где ...).


 
Сергей М. ©   (2008-07-02 11:51) [20]

Ну тогда твой цикл ожидания/выборки/диспетчеризации сообщений никуда не годится - "вис" происходит на GetMessage, когда из очереди выбраны и диспетчеризованы все имеющиеся там сообщения (т.е. очередь пуста).


 
dima_q   (2008-07-02 12:14) [21]


> Ну тогда твой цикл ожидания/выборки/диспетчеризации сообщений
> никуда не годится - "вис" происходит на GetMessage, когда
> из очереди выбраны и диспетчеризованы все имеющиеся там
> сообщения (т.е. очередь пуста).

Подскажите выход... пожалуйсто:) Каим должен быть цикл выборки сообщений, можно пример?


 
Сергей М. ©   (2008-07-02 13:17) [22]

Без учета таймаута примерно таким:

while not Terminated and (lastState <> 4) do
begin
 if PeekMessage(rMsg,0,0,0, PM_REMOVE) then
   DispatchMessage (rMsg)  
 else
   Sleep(0);
end;


 
dima_q   (2008-07-02 13:32) [23]

Уважаемый
> Сергей М. ©
огромнейшее, просто громадное Вам человеческое спасибо!!! Все работает... Вопрос закрыт.


 
igor_r ©   (2008-08-11 02:06) [24]

Всем доброго времени суток.

У меня задача схожая с dima_q, и отличается лишь тем, что данные передаются через SSL. Приложение пишу на ВСВ. Установил OpenSSL, подвязал сертификат. Если функция send пустая, идет обращение на сервер, запрашивается сертификат, получаю ответ с сервера. А если заполняю send данными получаю пустое окно ответа и сертификат не запрашивается. Скорее всего с передаваемыми данными что-то не так. Может что-то посоветуете.

Игорь


 
Сергей М. ©   (2008-08-11 08:43) [25]


> Если функция send пустая


Как это "пустая" ?


> заполняю send данными


Как можно "заполнить функцию данными" ?

Ерунда какая-то ..


 
igor_r ©   (2008-08-11 10:49) [26]

Функция send может быть как с параметром так и без него: send() или
send(data)

Игорь.


 
Сергей М. ©   (2008-08-11 12:21) [27]

И что ?

Вызов функции, с параметром или без, - это просто вызов функции, не более того.

Причем здесь какое-то там ее "наполнение" ?


 
igor_r ©   (2008-08-11 12:53) [28]

Сергей! Не придирайся к словам. Давай по существу проблемы...


 
Сергей М. ©   (2008-08-11 13:07) [29]

Проблема в тебе.
Я понятия не имею, что у тебя творится в этой самой send


 
igor_r ©   (2008-08-11 13:30) [30]

Спасибо за теплые слова.
Передаю на сервер через SSL следующее:
Variant bstr;
bstr.VType=VT_BSTR;
SysFreeString(bstr.bstrVal);
bstr.bstrVal=SysAllocString(L"<?xml\ version="1.0"\ encoding="WINDOWS-1251"?><request><tpnum>-1</tpnum></request>");
hRes=pXMLHTTP->send(bstr);
На локальном HTTP сервере передача информации проходит успешно.


 
Сергей М. ©   (2008-08-11 13:47) [31]


> На локальном HTTP сервере передача информации проходит успешно


Чудесно.

А какое отношение это имеет к STA и MTA ?


 
igor_r ©   (2008-08-11 14:12) [32]

Вопрос связан с передачей информации через SSL методом XMLHTTP.send(data).


 
Сергей М. ©   (2008-08-11 14:14) [33]


> igor_r ©   (11.08.08 14:12) [32]


А у автора вопрос был совершенно о другом.


 
igor_r ©   (2008-08-11 14:24) [34]

Но решаемые задачи схожие. Форум практически единственный который затронул эту тему. Да и автор вопроса ковырнул эту тему глубоко...


 
Сергей М. ©   (2008-08-11 14:48) [35]


> автор вопроса ковырнул эту тему глубоко


А ты внимательно читал ветку, перед тем как сделать вывод о якобы "схожести" ?


 
igor_r ©   (2008-08-11 14:52) [36]

Тема открытая автором XMLHTTP.
Сергей, тебе что поговорить не с кем? Лучше бы толковое что написал.
Считаю вопрос закрытым.


 
Сергей М. ©   (2008-08-11 15:01) [37]


> Тема открытая автором XMLHTTP


А дальше идет речь о конкретностях - об особенностях функционирования компонента в тех или иных условиях и режимах.

Ты же не сподобился даже изложить свои условия и режим эксплуатации компонента !

Какого же лешего ты ожидаешь услышать в ответ что-то "толковое" ?

Вот изволь сначала привести эти немаловажные подробности, потом и разговор будет предметным.



Страницы: 1 вся ветка

Текущий архив: 2010.08.27;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.046 c
2-1268082650
GoTo
2010-03-09 00:10
2010.08.27
Запись пути к файлу в БД


2-1266495492
NewGuest
2010-02-18 15:18
2010.08.27
Удаление компонентов в Run-Time


15-1275227407
Djony
2010-05-30 17:50
2010.08.27
Создание DLL в Delphi


2-1273664604
Дмитро
2010-05-12 15:43
2010.08.27
delphi


11-1216289923
BMouradov
2008-07-17 14:18
2010.08.27
потеря фокуса формы