DCOM самовосстанавливающиеся соединение
От: ZORK Россия www.zorkaltsev.com
Дата: 21.08.01 23:20
Оценка:
Я знаю что DCOM это далеко не самый умный выбор для сетевого соединения, но так уж случилось что щас мне надо сделать что-б работало

Общие условие задачи:
— клиент соединяется с сервером через DCOM
— соединение между клиентом и сервером может разрываться, как минимум по следующим причинам:
— клиент умер (GPF)
— физическое соединение (кабель) был разорван
— после соединения, возможно через значительный промежуток времени, соединение может восстанавливаться

Большинство проблем я решил создавая сессионый объект на сервере, и использовуя ::CoDisconnectObject(), когда этот сессионый объект не нужен. Есть еще несколько проблем, надо которыми я работаю, вот одна из них, другие напишу по мере надоедания мне искать ответ самому :):

— если клиент вызывает, сервер и во время обработки вызова, сервер визически перегружают (например нажимая Reset), клиент остается в ожидании ответа — и это навсегда. Есть CoCancelCall, и прочие функции, но мои эксперементы пока не привели к желаемому результату. Есть идеи, как сделать что-бы по timeout'у вызов на клиентской стороне прикращался?
Думать надо ...головой :)
Re: DCOM самовосстанавливающиеся соединение
От: alexm1202 Россия  
Дата: 22.08.01 11:11
Оценка:
Здравствуйте ZORK, вы писали:

ZORK>- если клиент вызывает, сервер и во время обработки вызова, сервер визически перегружают (например нажимая Reset), клиент остается в ожидании ответа — и это навсегда. Есть CoCancelCall, и прочие функции, но мои эксперементы пока не привели к желаемому результату. Есть идеи, как сделать что-бы по timeout'у вызов на клиентской стороне прикращался?


Гм, насколько я понял CoCancelCall тебе не подходит, он предназначен для того чтобы _попросить_ сервер быстренько вырнуться из вызова, т.е. сервер для этого должен быть жив. Слушай, а с чего ты взял, что DCOM-вызовы не возвращаются по timeout?
Вот, посмотри:
http://support.microsoft.com/support/kb/articles/Q255/1/98.ASP

BR, alexm1202
BR, Alex.
Re[2]: DCOM самовосстанавливающиеся соединение
От: ZORK Россия www.zorkaltsev.com
Дата: 22.08.01 12:00
Оценка:
Здравствуйте alexm1202, вы писали:

A>Гм, насколько я понял CoCancelCall тебе не подходит, он предназначен для того чтобы _попросить_ сервер быстренько вырнуться из вызова, т.е. сервер для этого должен быть жив. Слушай, а с чего ты взял, что DCOM-вызовы не возвращаются по timeout?


Во-первых, уточню, у упрожняюсь на между двумя Windows 2000 системами. И я использовал Apartment Thread Model для клиента и сервера.

Ну что не возвращается, я узнал просто — создал client/server DCOM приложение, и сделал так что при вызове клиентом сервера, методе сервера запускается for(;){}, так что он никогда контроль не возвращает. При этом если сервер тормозишь дебагером, то клиент узнает про то что сервер ушел, а вот если тупо нажимаешь Reset на компе, то клиент ничего не замечает. Я в порядке эксперемента пару раз ждал больше 10 минут — и клиент продолжал весеть, даже уже тогда когда компьютер, на котором был DCOM сервер, загружался обратно.

А если верить этой статье — то вроде timeout должен наступать максимум в течение 90 сек., но похоже что-то не так. При чем в других источника MC рассказывает про то что они проверяют DCOM соединение, и если в течение 6 мин (по умолчанию) связь с объектом не восстановится, то они забывают про него — очевидно, для этого случая, это тоже не работает.

Я думаю CoCancelCall может оказаться правильным направлением — так как для того что-бы сказать серевру, что надо прервать обработку вызова, надо к серверу обратиться, и тут должен произойти как минимум RPC timeout. Может я не прав, но похоже что при посто вызове, DCOM посылает сообщение серверу, и сидит в каком-то цикле обработки приходящих сообщении, и ничего больше не проверяет. А так как сервер умирает быстро, и без возможности сообщить клиенту что он отвалил, клиент продолжает сидеть в этом цикле до упора.
Думать надо ...головой :)
Re[3]: DCOM самовосстанавливающиеся соединение
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.08.01 16:12
Оценка:
Здравствуйте ZORK, вы писали:

Почитай вот это http://www.optim.ru/cs/2000/4/com_htm/com_2.asp
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: DCOM самовосстанавливающиеся соединение
От: ZORK Россия www.zorkaltsev.com
Дата: 22.08.01 21:21
Оценка:
Здравствуйте VladD2, вы писали:

VD>Почитай вот это http://www.optim.ru/cs/2000/4/com_htm/com_2.asp


Спасибо! — натолкнуло на мысли и эксперементы. Оказалось:

— можно сделать cancel сообщения в ATM, если добавить IMessageFileter::MessagePending и возвращать из него после timeout'а PENDINGMSG_CANCELCALL, но так как MessagePanding вызывается, только тогда когда приходит Windows сообщение, то полезно перед COM-вызовом сделать ::SetTimer(wnd, timeout), что-бы сообщение точно пришло, а то опять будет весеть до бесконечности, особенно если это проиходит в нитке не связанной с видимым окном

— нашел у MS следующие рассуждения http://msdn.microsoft.com/library/en-us/com/hh/com/asyncall_8yur.asp?frame=true , из которых следует что CoCancelCall более общий способ прерывать COM-вызовы — он работает для любой модели, в то время как IMessageFileter только для ATM

— вернулся обратно к эксперементу с CoCancelCall — оказалось, что я был рядом. Выяснилось, что для того что-бы прервать COM команду, надо вызвать CoCancelCall пару раз, кстати такое же наблюдалось с IMessageFileter::MessagePending. Надо полагать, при удаленном вызове есть какая-то внутреняя вложенность вызовов. После того как watchdog нитка стала многократно вызывать CoCancelCall — вызовы стали успешно прерываться. Так что проблема решена

Всем спасибо!
Думать надо ...головой :)
Re[5]: DCOM самовосстанавливающиеся соединение
От: LioLick  
Дата: 01.09.04 06:23
Оценка:
Здравствуйте, ZORK, Вы писали:

ZOR>- вернулся обратно к эксперементу с CoCancelCall — оказалось, что я был рядом. Выяснилось, что для того что-бы прервать COM команду, надо вызвать CoCancelCall пару раз, кстати такое же наблюдалось с IMessageFileter::MessagePending. Надо полагать, при удаленном вызове есть какая-то внутреняя вложенность вызовов. После того как watchdog нитка стала многократно вызывать CoCancelCall — вызовы стали успешно прерываться. Так что проблема решена


Добрый день!
Я занимаюсь подобной проблемой с ::CoCancelCall. В основном меня интересует прерывание (разумеется, корректное) вызова ::CoCreateInstanceEx для создания объекта на удаленной машине если сервер недоступен.
Пока никаких проблем обнаружено не было, т.е. дополнительных вызовов ::CoCancelCall не понадобилось.
Если не трудно, не подскажете, в каких случаях возникают подобные ситуации и что возвращает ::CoCancelCall в таких случаях при первом вызове?
Спасибо.
GL!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.