Форум: "Основная";
Текущий архив: 2012.02.12;
Скачать: [xml.tar.bz2];
ВнизОшибка Interface not supported при подключении через TDCOMConnect Найти похожие ветки
← →
Alexander_K (2010-09-10 11:46) [0]Добрый день!
Ситуация следующая:
Я написал сервер приложений (по технологии MIDAS). В клиентской части, для соединения с сервером приложений использую компонент TDCOMConnection.
При попытке подключения к серверу приложений на локальном компьютере (установка свойства Connected у TDCOMConnection), сервер запускается и свойство Connected переходит в true, то есть все работает.
Если же я переношу сервер приложений на другой комьютер (Win XP), соответственно настоив DCOM безопасность на нем, при попытке установить свойство Connected у TDCOMConnection в true выдается ошибка:
Interface not supported, и соответственно Connected в true не переходит, причем форма сервера на удаленном компьютере появляется.
Теперь о конфигурации сети:
Сервер не в домене, а мой компьютер в домене.
Поскольку к данному серверу приложений будут коннектится очень много пользователей, и находящихся в домене и нет, то я посчитал что надо настроить доступ DCOM без ограничений для всех, и настроил безопасность COM следующим образом:
Через службу компонентов -> свойста->Мой компьютер->Свойства по умолчанию назначил свойства:
Разрешить использование DCOM на этом компьютере
уровень проверки подлинности - Нет
Уровень олицетворения - Анонимное
Безопасность COM:
Добавил группы SYSTEM, анонимный вход, все, гости, интерактивные, сеть, удаленный доступ и разрешил им полный доступ в правах доступа и в разрешениях на запуск и активизацию, так же в ограничениях я тоже добавил все эти группы и установил везде все галочки.
Потом в Настройка DCOM нашел мой сервер и в свойствах сделал следующее:
Уровень проверки подлинности - Нет
Какую учетную запись использовать для запуска - Текущий пользователь
Соответственно вопрос:
почему может не работать?
Может каких-то dll-ек не хватает на сервере? (ведь делфей там не стоит)
Я так понимаю на клиентском компьютере DCOM настраивать не надо?
Очень прошу помощи, заранее благодарен!
← →
Alexander_K (2010-09-10 13:17) [1]В общем я разобрался с проблемой, я разрешил группу гостей везде, и в политиках безопасности тоже, и вроде все заработало
← →
Loginov Dmitry © (2010-09-10 22:54) [2]Не рекомендую связываться с TDCOMConnection. Настройка разрешений DCOM на сервере - это вечная головная боль. И не всегда удается его настроить. И винда не всегда работает как должна. Иногда что-то портится, приходится винду переустанавливать. Приходится отключать сетевые экраны, поскольку TCP-порты DCOM-а на сервере - это рандом.
Все тоже самое можно организовать через SocketConnection, при этом на сервере должен быть открыт вполне конкретный TCP-порт (может несколько), и запущена одна дополнительная служба Borland SocketServer (причем она есть в демках в исходниках, и на ее основе можно делать свои приложения). В настройки DCOM-а даже лазить не придется.
← →
Loginov Dmitry © (2010-09-10 22:57) [3]
> Я так понимаю на клиентском компьютере DCOM настраивать
> не надо?
В свойствах объекта DCOM "Мой компьютер" необходимо поставить "Уровень проверки подлинности - Подключение".
← →
_Юрий (2010-09-11 10:27) [4]c Borland SocketServer тоже не все гладко, иногда она имеет свойство вдруг начать дурить, и не успокаивается без перезапуска.
В любом случае, на клиенте лучше сделать настройку - как соединяться - через DCom или Socket"ы (абстрагироваться от конкретной реализации подключения несложно, ибо есть общий предок), а на сервере всегда должен работать Borland SocketServer.
А совсем по хорошему, дурная это технология. Новый проект ни за что не стал бы делать таким образом
← →
gnom (2010-09-13 15:20) [5]>_Юрий
А почему не стали бы и на что заменили бы?
Если можно - поподробней
← →
_Юрий (2010-09-14 00:23) [6]
> gnom (13.09.10 15:20) [5]
Используя DCom, мы получаем в общем то всего два преимущества - автозапуск сервера когда надо, и готовый транспорт.
Первое преимущество на практике превращается в недостаток - в реальной жизни все равно всегда приходится запускать сервер руками, а в случае необходимости замены внезапные старты в момент попытки замены создают лишь дополнительный геморрой.
И кроме того, существуют недостатки: отсутствие полного контроля за происходящим (к VCL доверия в последнее время стало меньше, а там работает большое количеств их кода),
сложности в передаче информации об исключении на сторону клиента (потеря класса исключения, в ряде случаев потеря и текста тоже),
сложность настройки безопасности при DCom, а в случае сокетов - сбои в работе службы,
сложность сопровождения - на практике при изменении интерфейса часто приходится пересобирать всех клиентов, система получается громоздкой.
По какой то причине время от времени (раз в три недели) сервер внезапно начинает сыпать исключениями OutOfMemory, хотя ликов там нет - это проверялось. Иногда (редко) в памяти оказывается два процесса, хотя выбранная модель должна такое исключать в принципе.
На мой взгляд, минусы перевешивают плюсы.
> и на что заменили бы?
учитывая, что много клиентов - на web
← →
Alexander_K (2010-09-14 14:04) [7]Да в том то и дело, что программа работает через сокет сервер, все нормально работает уже долгое время, а совсем недавно возникла необходимость поставить еще один такой же сервер приложений в другом офисе с той же программой (офисы связаны через впн), так вот почему-то на новом сервере приложений происходит падение серверной части случайным образом. Причем никакой ошибки не выдается.
То есть клиент работает, и в какой-то момент, при обращении клиента к серверу (причем совершенно случайно) серверная часть просто закрывается без каких либо ошибок, ну а клиентская при этом выдает: Сервер RPC недоступен....
Вот я и хотел попробовать может через dcom, а не через сокет сервер... при этом переписывать там практически ничего не надо...
Но вот оказалось что и это почему-то не помогло...
← →
Плохиш © (2010-09-14 14:29) [8]Подозреваю, что там ошибка в программе.
← →
Alexander_K (2010-09-14 15:26) [9]Да тоже думал что ошибка....
но вроде на одной системе все работает без вопросов....
да методы на сервере приложений довольно простые, которые заключаются в основном в присвоении строки sql-запроса и выполнение его....
да и перехват ошибок в сервере у меня в этих методах стоит, ругалось бы хотябы, да и падает все не в одном определенном месте...
вообщем тяжело это отловить все...
← →
_Юрий (2010-09-15 00:20) [10]
> Alexander_K (14.09.10 15:26) [9]
> Да тоже думал что ошибка....
> выдается ошибка:
> Interface not supported, и соответственно Connected в true
> не переходит, причем форма сервера на удаленном компьютере
> появляется.
В точности такая ошибка будет например, если произошло исключение в конструкторе объекта-сервера при автозапуске. И существует масса возможных причин, почему один и тот же код может на одной системе работать, а на другой давать исключение, начиная с тех же прав.
> почему-то на новом сервере приложений происходит падение
> серверной части случайным образом. Причем никакой ошибки
> не выдается.
В системном журнале есть записи по этому поводу ?
← →
Loginov Dmitry © (2010-09-15 00:30) [11]
> в реальной жизни все равно всегда приходится запускать сервер
> руками
Но это именно в Вашем случае! В других случаях может потребоваться автоматический запуск. Важно еще следующее: обеспечить правильность работы и минимизировать время коннекта.
> а в случае необходимости замены внезапные старты в момент
> попытки замены создают лишь дополнительный геморрой.
Как одно из возможных решений: проверять на наличие определенного файла в определенном месте, и если он есть, то вырубать DCOM-сервер (наподобие как сделано в ASP.NET)
> И кроме того, существуют недостатки: отсутствие полного
> контроля за происходящим (к VCL доверия в последнее время
> стало меньше, а там работает большое количеств их кода)
Есть конечно недостатки реализации VCL. На вскидку:
Проблема №1: объект DCOM иногда создается раньше, чем проинициализируется основной поток. А логика объекта DCOM иногда зависит от объектов, создаваемых основным потоком. Выход: приостановить создание объекта DCOM до окончания инициализации основного потока.
Проблема №2: при одновременном создании 2х объектов DCOM можно словить AV. Это связано с тем, что TRemoteDataModule, будучи наследником от TDataModule, регистрирует себя в списке Screen.DataModules, а список этот не защищен ничем. Выход: сделать override-конструктор, а строку inherited заключить в критическую секцию.
Проблема №3: нельзя выпускать исключения, которые возникают в событии TRemoteDataModule.OnCreate. Их нужно отлавливать с помощью TRY..EXCEPT и самостоятельно обрабатывать (например, сделать запись в лог).
Все эти проблемы - это ошибки, допущенные при проектировании VCL.
Основная же проблема - это разработчик, а вернее его зачастую слабое понимание основ разработки с DCOM-серверов.
> сложности в передаче информации об исключении на сторону
> клиента (потеря класса исключения, в ряде случаев потеря
> и текста тоже)
Есть такая проблема. Я вообще предпочитаю в DCOM-сервере делать всего лишь одну внешнюю функцию с одним параметром OleVariant, возвращающую также OleVariant. А уже эта функция вызывает необходимые функции (в зависимости от параметров в OleVariant). При таком подходе очень просто отловить исключения и сгенерировать другое исключение (просто raise Exception.Create(...)), в тексте которого можно указать имя класса оригинального исключения.
>
> сложность сопровождения - на практике при изменении интерфейса
> часто приходится пересобирать всех клиентов, система получается
> громоздкой.
Как раз с этим никаких сложностей, если работа организована через AppServer.
Интерфейс не должен переделываться, только дорабатываться, с соответствующим наращиванием номера версии в DCOM-сервере. Конечно "должен" или "не должен" зависит от разработчика.
> По какой то причине время от времени (раз в три недели)
> сервер внезапно начинает сыпать исключениями OutOfMemory,
> хотя ликов там нет - это проверялось.
Не сталкивался. Имхо, ошибка в программа (быть может в части VCL).
> Иногда (редко) в памяти оказывается два процесса, хотя выбранная
> модель должна такое исключать в принципе.
Такое может быть, если в настройках DCOM установлен тип запуска "Запускающий пользователь". Если указан "Текущий пользователь" или "Заданный пользователь", то такого быть не должно (если конечно вручную кто-нибудь сервер не запустит).
> На мой взгляд, минусы перевешивают плюсы.
Из недавних разбирательств:
- С одним клиентом неделю по телефону DCOM настраивали. Оказалось, что у него на компе было включено 2 файрвола. При мне лазил отключал файрвол от винды. Кто ж знал, что у него там еще и файрвол от нортона :) Он вроде там и админ, но не знал. Я и подавно.
- Windows 7, подключаясь через DCOM к Windows XP, логинится как "Анонимный пользователь". И судя по всего, этот самый "Анонимный пользователь" в группу "Все" не входит. Вообще, для каждой винды все новые и новые заморочки с настройками DCOM. И эти настройки с каждым разом все сложнее и сложнее.
← →
Loginov Dmitry © (2010-09-15 00:34) [12]
> но вроде на одной системе все работает без вопросов....
> да методы на сервере приложений довольно простые, которые
> заключаются в основном в присвоении строки sql-запроса и
> выполнение его....
Если синхронизация потоков кривая (а в DCOM-сервере объект DCOM создается НЕ в основном потоке), то это достаточно быстро выявляется на системе с многоядерным процессором.
← →
Alexander_K (2010-09-15 09:22) [13]_Юрий (15.09.10 00:20) [10]
> выдается ошибка:
> Interface not supported, и соответственно Connected в true
> не переходит, причем форма сервера на удаленном компьютере
> появляется.
С этим я уже разобрался, о чем писал во втором сообщении
А вот с падением сервера приложений нет...
← →
Alexander_K (2010-09-15 09:41) [14]Loginov Dmitry © (15.09.10 00:34) [12]
Дело в том, что у меня там используется модель Appartment. Поэтому я так понял, каждый клиент должен обрабатываться в своем потоке. Причем при подключении каждого клиента, форма сервера для каждого клинента открывается своя.
← →
Alexander_K (2010-09-15 09:58) [15]Loginov Dmitry © (15.09.10 00:34) [12]
Вообще сервер приложений представляет собой программу, написаную на C++ Builder:
Remout Data Module используется модель Appartment, в нем соответственно компоненты DOA (OracleSession,OracleDataSet и Датасет провайдеры)
и соответственно методы, примерно такого типа:
STDMETHODIMP TServerImpl::SetSQL17(BSTR sql)
{
try
{
m_DataModule->OracleDataSet17->Close();
m_DataModule->OracleDataSet17->SQL->Text = sql;
}
catch (Exception &exception)
{
return E_FAIL;
}
return S_OK;
}
А поскольку используется Appartment, то я так понял, для каждого клиента должна создаваться своя копия RDM-а в отдельном потоке.
Может я конечно не правильно все понимаю, и тут надо что-то дополнительно синхронизировать?
← →
Loginov Dmitry © (2010-09-15 15:08) [16]
> А поскольку используется Appartment, то я так понял, для
> каждого клиента должна создаваться своя копия RDM-а в отдельном
> потоке.
>
> Может я конечно не правильно все понимаю, и тут надо что-
> то дополнительно синхронизировать?
Что такое m_DataModule?
Каким образом, где и в какой момент он создается?
← →
Alexander_K (2010-09-15 15:12) [17]Он описан в ATLVCL.H
Вот часть класса в котором он описан:
template <class DM, class T , class Intf, const IID* piid, const GUID* plibid>
class ATL_NO_VTABLE IAppServerImpl: public IDispatchImpl<Intf, piid, plibid>
{
private:
TCOMCriticalSection m_CS;
public:
// Note: This data module _must_ derive from TCRemoteDataModule.
DM* m_DataModule;
IAppServerImpl()
{
m_DataModule = new DM(NULL);
}
~IAppServerImpl()
{
m_DataModule->Free();
}
← →
Alexander_K (2010-09-15 15:17) [18]Вообще, я пользуюсь BDS2006, и я решил тот же самый сервер приложений переписать на делфи....
соответственно при создании RDM ClassInstancing я использовал ciMultiInstance, и ThreadingModel соответственно tmApartment
методы соответственно приобрели примерно такой вид:
procedure TServerSpravD.SetSQL17(const sql: WideString);
begin
OracleDataSet17.Close();
OracleDataSet17.SQL.Text := sql;
end;
И все равно падения не прекратились.....
← →
Alexander_K (2010-09-15 16:58) [19]для чистоты эксперимента попробую сейчас ClassInstancing поставить ciSingleInstance и ThreadingModel поставить tmSingle и попробую посмотреть будет падать или нет... правда здесь на каждый коннект будет запускаться по отдельному серверу
← →
Дмитрий Белькевич (2010-09-15 23:09) [20]
> так вот почему-то на новом сервере приложений происходит
> падение серверной части случайным образом. Причем никакой
> ошибки не выдается.
Рекомендую попробовать эврикалог, очень помогает, особенно в непонятных случаях. Можете на триале потестить.
← →
Alexander_K (2010-09-16 08:02) [21]Дмитрий Белькевич (15.09.10 23:09) [20]
Что за зверь?
← →
Alexander_K (2010-09-16 10:05) [22]Попробовал ClassInstancing поставить ciSingleInstance и ThreadingModel поставить tmSingle - все так же падает :(
← →
Дмитрий Белькевич (2010-09-16 16:29) [23]www.eurekalog.com
← →
_Юрий (2010-09-16 19:41) [24]
> Loginov Dmitry © (15.09.10 00:30) [11]
>
>
> > в реальной жизни все равно всегда приходится запускать
> сервер
> > руками
>
>
> Но это именно в Вашем случае! В других случаях может потребоваться
> автоматический запуск. Важно еще следующее: обеспечить правильность
> работы и минимизировать время коннекта.
Не могу представить такого случая. Можно пример?
Кстати, с точки зрения ускорения коннекта опять таки лучше, чтобы уже был запущен.
> Интерфейс не должен переделываться, только дорабатываться,
> с соответствующим наращиванием номера версии в DCOM-сервере.
> Конечно "должен" или "не должен" зависит от разработчика.
>
Никогда не переделывать - не очень хорошо. Время от времени требуется рефакторинг, старые методы отмирают, у живых методов меняются сигнатуры, постоянно тащить за собой "всю историю" - повышать энтропию системы.
> Я вообще предпочитаю в DCOM-сервере делать всего лишь одну
> внешнюю функцию с одним параметром OleVariant, возвращающую
> также OleVariant.
Это нехорошо тем, что мы теряем независимость от языка, на котором написан клиент. Причем бывает так, что в начале жизни системы такое ограничение кажется приемлемым, а потом (через два года) внезапно оказывается, что таки нет.
> - С одним клиентом неделю по телефону DCOM настраивали.
Это имхо самый страшный кошмар, который может случиться у программиста (не считая потери данных, конечно):-)
> Alexander_K (15.09.10 09:22) [13]
>
> _Юрий (15.09.10 00:20) [10]
>
> > выдается ошибка:
> > Interface not supported, и соответственно Connected в
> true
> > не переходит, причем форма сервера на удаленном компьютере
> > появляется.
>
> С этим я уже разобрался, о чем писал во втором сообщении
Ну так а причина то все равно осталась невыясненной. Почему именно - если форма появляется.
Это не "разобрался" ,а "нашел состояние, при котором ошибка не возникает"
← →
Alexander_K (2010-09-24 15:34) [25]Похоже проблема решена, поставил компоненты DOA поновее, и вроде пока все (тьфу, тьфу, тьфу) работает....
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2012.02.12;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.004 c