Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

XMLHTTP [D7, WinXP]


Страницы:   1 2

dima_q ©   (2008-06-30 13:13:00) 

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


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


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

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

   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 10:16:00) [22]


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


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


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


> Кого ?!

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


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


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


Кого ?!


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


> Сергей М. ©

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


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


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


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

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


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

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


dima_q   (2008-06-30 18:30:00) [28]

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


clickmaker   (2008-06-30 18:16:00) [29]

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


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


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

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


clickmaker   (2008-06-30 17:59:00) [31]

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


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

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


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

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


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


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


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

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

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


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

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


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


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

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


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

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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо