Форум: "Сети";
Текущий архив: 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.078 c