Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.059 c
2-1268812490
Вася
2010-03-17 10:54
2010.08.27
Как узнать, существует ли компонент?


2-1274530341
Delphist2
2010-05-22 16:12
2010.08.27
method insert класса range завершен неверно


15-1274119662
Masolin_gazin
2010-05-17 22:07
2010.08.27
Как удалить сообщения программы?


15-1272460353
Amoeba_
2010-04-28 17:12
2010.08.27
Академики шарлатаны. ФО РАН посвящается.


2-1270706035
novai
2010-04-08 09:53
2010.08.27
Использование Format





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский