Создание серверов приложений с помощью Delphi 3

Наталия Елманова

Содержание

Введение

Данная статья посвящена созданию многозвенных приложений с помощью Borland Delphi 3 и MIDAS (Multi-tier Distributed Application Service Suite) - нового продукта компании Borland International, предназначенного для эксплуатации созданных с помощью Delphi 3 серверов приложений, и, в частности, его составной части - OLEnterprise, продукта корпорации Open Environment, ставшей в прошлом году подразделением Borland. Trial-версия этого продукта входит в комплект поставки Delphi 3.0 Client/Server Suite.

Зачем нужны многозвенные информационные системы

Информационные системы, созданные на основе классической архитектуры клиент/сервер, называемые двухзвенными системами или системами с "толстым" клиентом, состоят из сервера баз данных, содержащего сгенерированные тем или иным способом таблицы, индексы, триггеры и другие объекты, реализующие бизнес-правила данной информационной системы, и одного или нескольких клиентских приложений, предоставляющих интерфейс пользователя и производящих проверку допустимости и обработку данных согласно содержащимся в них алгоритмам. Если говорить о клиентских приложениях, созданных с помощью Delphi, для доступа к источникам данных они используют вызовы функций прикладных программных интерфейсов клиентских частей соответствующих серверных СУБД. Эти вызовы осуществляются обычно посредством использования библиотеки Borland Database Engine (BDE), хотя в целом это не является обязательным (например, некоторые пользователи Oracle непосредственно вызывают функции Oracle Call Interface из Delphi-приложений). Соответственно подобное клиентское приложение требует наличия на компьютере конечного пользователя клиентской части используемой серверной СУБД (и наличия лицензии на ее использование) и присутствия в оперативной памяти набора динамически загружаемых библиотек как из клиентской части, так и из BDE (либо иной заменяющей ее библиотеки), таких, как драйверы баз данных, библиотеки, содержащие функции API клиентских частей, и др. Это усложняет технические требования, предъявляемые к аппаратной части клиентской рабочей станции, и в конечном итоге приводит к удорожанию всей системы в целом.

Другим фактором, приводящим к удорожанию эксплуатации информационной системы, является необходимость инсталляции и конфигурации BDE и клиентской части серверной СУБД, что нередко является весьма трудоемким процессом, особенно при большом количестве и неоднородном парке рабочих станций.

Выходом из этой ситуации является создание систем с так называемым "тонким" клиентом, в частности, с клиентом, не содержащим в своем составе BDE и клиентскую часть серверной СУБД. В этом случае функциональность, связанная с доступом к данным (а нередко и какая-либо иная функциональность), возлагается на другое приложение, называемое обычно сервером приложений, и являющееся клиентом серверной СУБД. В свою очередь, клиентские приложения обращаются не непосредственно к серверной СУБД посредством вызова функций клиентских API, а к серверу приложений, являющемуся для них источником данных, при этом собственно клиентская часть серверной СУБД и библиотеки типа BDE на рабочей станции, где используется такое клиентское приложение, присутствовать не обязаны. Вместо них используется одна-единственная динамически загружаемая библиотека dbclient.dll размером 154 Кб. Таким образом, созданная информационная система становится трехзвенной, а сервер приложений является средним звеном в цепи "тонкий клиент - сервер приложений - сервер баз данных" и, соответственно, относится к классу продуктов middleware.

Как может быть практически реализована данная технология? С одной стороны, с помощью набора компонентов и классов Delphi 3, обеспечивающих создание серверов приложений и клиентских частей, а, с другой стороны, с помощью MIDAS, позволяющего осуществлять запуск удаленных серверов приложений, осуществлять межреестровый обмен сведениями об OLE-серверах и оптимизировать нагрузку в случае использования нескольких серверов приложений. В данной статье будет рассмотрен простейший практический пример реализации подобной трехзвенной системы.

Подготовка данных для сервера приложений

Для создания сервера приложений нам потребуются какая-либо серверная СУБД, клиентом которой будет данный сервер приложений, и тестовые таблицы, которые будут перенесены на сервер баз данных. В рассмотренных в настоящей работе примерах используются Personal Oracle for Windows 95 и Oracle Workgroup Server 7.2 for Windows NT (90-дневные trial-версии), но не возбраняется использовать в качестве источника данных любую серверную СУБД (и, вообще говоря, даже набор таблиц dBase или Paradox).

Создадим нового пользователя Oracle с правами CONNECT и RESOURCE и от его имени перенесем c помощью утилиты Data Migration Wizard таблицы CLIENTS.DBF и HOLDINGS.DBF из базы данных DBDEMOS, входящей в комплект поставки Delphi 3, в базу данных Personal Oracle for Windows 95 или Oracle Workgroup Server 7.2 for Windows NT. После этого можно приступить к созданию простейшего сервера приложений, являющегося, с одной стороны, клиентом серверной СУБД, и, с другой стороны, сервером конечного пользовательского приложения, которое становится при этом так называемым "тонким" клиентом.

Создание сервера приложений

Создание сервера приложений начнем с создания обычной формы (можно небольшого размера, так как основное ее назначение - быть индикатором запущенного сервера приложений) со значением свойства FormStyle равным fsStayOnTop (рис.1). Вообще говоря, появление на экране главной формы в общем случае не является обязательным. Далее создадим обычный модуль данных, содержащий компонент TDataBase, указывающий на серверную СУБД. Для простоты установим свойство LoginPrompt этого компонента равным False, а в свойстве Params укажем имя пользователя, от имени которого будет запущен сервер приложений, и его пароль:
Username=user1

Password = user1

Рис.1. Главная форма и модуль данных сервера приложений

Далее из репозитария объектов (доступ к которому осуществляется выбором пункта меню File/New…) со страницы New следует выбрать объект Remote Data Module (рис.2).

Рис.2. Выбор удаленного модуля данных из репозитария объектов

Remote Data Module имеет принципиальное отличие от обычного DataModule, заключающееся в том, что объекты, помещенные в него, могут иметь COM-интерфейс.

Создание Remote Data Module начинается с запуска эксперта Remote Dataset Wizard, в котором определяется, в частности, имя класса, под которым данный сервер приложений (он же OLE-сервер) будет зарегистрирован в реестре (рис.3):

Рис.3. Выбор имени класса

Далее в созданный удаленный модуль данных поместим два компонента TTable, связанных с компонентом Database1 и указывающих на только что созданные таблицы CLIENTS и HOLDINGS, а также два компонента TProvider. Установим значения свойств DataSet компонентов TProvider равными именам соответствующих компонентов TTable. Установим связь master/detail между таблицами по полю ACCT_NBR. Откроем таблицы (рис. 4)

Рис.4. Содержимое удаленного модуля данных

Далее из контекстного меню компонентов TTable и TProvider нужно выбрать опции

Последние две опции являются, вообще говоря, необязательными, так как компоненты TProvider обеспечивают другим приложениям, функционирующим в сети, доступ к данным, содержащимся в компонентах TTable и TQuery,

Если теперь исследовать полученную библиотеку типов (Type library), можно обнаружить, что COM-объект, который будет создаваться при запуске данного приложения, обладает интерфейсом, осуществляющим доступ извне к компонентам MyProv1, MyProv2, Table1 и Table2. (рис. 5).

Рис.5. Библиотека типов созданного проекта

Далее следует сохранить проект и скомпилировать приложение.

Рекомендуется убедиться, что оно зарегистрировано в реестре под выбранным ранее именем. Если тем не менее по каким-либо причинам этого не произошло, следует запустить наше приложение-сервер с параметром /regserver. После этого проект следует закрыть.

Создание локального клиентского приложения (на том же ПК, что и сервер)

Закрыв проект созданного только что сервера, можно приступить к созданию клиентского приложения. Создадим главную форму приложения и обычный модуль данных, который должен быть видим из главной формы (этого можно достичь путем выбора опции: File/Use unit...). В модуль данных поместим один компонент TRemoteServer, два связанных с ним компонента TClientDataSet и два связанных с ними компонента TDataSource.
Рис.6. Модуль данных клиентского приложения

Попробуем установить свойство ServerName компонента RemoteServer1 (выбрав его из выпадающего списка или введя вручную). После этого, если в реестре есть соответствующая запись, автоматически будет установлено значение свойства ServerGUID. При этом сервер приложений, созданный ранее, должен автоматически запуститься, о чем будет свидетельствовать появившаяся на экране его главная форма.

После этого можно установить нужные значения свойств ProviderName компонентов TClientDataSet, выбрав их из выпадающего списка (так как сервер приложений выбран, все его доступные через интерфейс свойства становятся видны в среде разработки). После этого можно установить связь master/detail между таблицами по общему полю ACCT_NBR.

Далее нужно установить значения свойства Active компонентов TClientDataSet равными True и связать интерфейсные элементы главной формы приложения с соответствующими полями таблиц, доступных через запущенный сервер приложений.

Рис.7. Главная форма клиентского приложения

Теперь можно скомпилировать и запустить приложение. Отметим, что при запуске приложения из среды разработки с сервером приложений соединены два клиента - среда разработки и скомпилированное клиентское приложение. При желании можно с помощью утилиты SQL Monitor проследить, какие именно запросы созданный нами сервер приложений направляет серверу баз данных.

Данный пример был выполнен на ПК Pentium-120/32 МБ c ОС Windows 95 с использованием. Personal Oracle 7.2 for Windows 95 (90-дневная trial-версия)и Delphi 3.0. При этом во время отладки приложения был постоянно загружен MicrosoftWord 7.0.

Удаленный клиент с использованием OLEnterprise

В рассмотренном выше примере сервер баз данных, сервер приложений и приложение-клиент выполнялись на одном том же компьютере. Более интересным для практического применения представляется случай использования для этой цели разных компьютеров, связанных, например, локальной сетью. В этом случае возникает проблема обмена данными между реестрами сервера приложений и клиента, которая может быть решена различными способами. Одним из таких способов является использование OLEnterprise - составной части MIDAS.

Для использования OLEnterprise следует установить его полную версию (содержащую фабрику классов - Class Factory) на компьютер, на котором будет запущен сервер приложений, и Run-time-версию - на компьютер, содержащий приложение-клиент.

На компьютере, содержащем полную версию OLEnterprise, следует запустить приложение Business Object Broker, обеспечивающее соединение клиента с сервером и равномерное распределение нагрузки между серверами приложений, если их несколько. Далее следует запустить приложение Object Factory. Затем следует запустить Object Explorer - утилиту, предназначенную для межреестрового обмена сведениями о серверах приложений между компьютерами в сети. Далее следует найти созданный ранее сервер приложений среди полученного из реестра данного компьютера списка OLE-серверов и экспортировать его (иногда это называется публикацией объекта), выбрав в меню пункт Object/Export (рис.8). После этого OLE-сервер можно будет "увидеть" с удаленных компьютеров в сети как доступный для них объект.

Рис.8. Публикация объекта с помощью Object Explorer

На рабочей станции, где будет запущено приложение-клиент, следует запустить Object Explorer и соединиться с реестром компьютера, содержащего сервер приложений (Registry/Connect…). Все экспортированные объекты после этого будут видны в списке OLE-серверов удаленного реестра. Далее следует импортировать выбранный сервер приложений (Object/Import), отметив, что приложение будет выполняться на том компьютере, где оно содержится. После этого можно убедиться, что данный OLE-сервер содержится в реестре рабочей станции (например, запустив входящий в состав операционной системы редактор реестра).

Теперь можно слегка изменить клиентское приложение, выбрав значение свойства ComputerName компонента TRemoteServer из списка доступных в локальной сети компьютеров. При попытке установить свойство Connected этого компонента равным True сервер приложений будет найден в реестре и запущен на удаленном ПК.

Отметим, что если пользователь редактирует данные в клиентском приложении, они не переносятся непосредственно на сервер баз данных, а вместо этого кэшируются. Для инициации процесса реального сохранения в базе данных используется метод ApplyUpdates компонента TClientDataSet. В качестве параметра этот метод использует целое число, равное максимально допустимому числу ошибок сервера, после которого следует прекратить попытки физического сохранения данных (значение -1 означает, что следует пытаться сохранить все данные независимо от числа ошибок). Почему предусмотрена возможность ошибок сервера? Ответ очевиден - клиентское приложение может ничего не знать о правилах ссылочной целостности и иных ограничениях, содержащихся на сервере баз данных, и только попытка физического сохранения изменений в базе данных может выявить их нарушения (вспомним, что на клиентской рабочей станции может даже не быть библиотеки BDE).

Отметим также, что установить связи между таблицами можно как на сервере приложений, так и в клиентском приложении, и разработчик может выбрать, что удобнее с точки зрения эффективности работы и функциональности.

Данный пример был выполнен в одном из классов Учебного центра Interface Ltd. Особо хотелось бы обратить внимание на довольно скромные требования к ресурсам как компьютера, содержащего сервер приложений, так и рабочих станций, на которых выполнялись клиентские приложения (табл.1)

Таблица 1. Технические характеристики использованных ПК и ПО при соединении клиента и сервера приложений с помощью OLEnterprise

Компоненты распределенной системы ПО ПК
Сервер БД Windows NT Server 4.0 + Oracle Workgroup Server 7.2 (Trial 90-day version) for Windows NT Pentium-133/32 MB RAM
Сервер приложений Windows 95 486 DX2-66/16 MB RAM
Клиент 1 Windows NT Server 4.0 Pentium-133/32 MB RAM (тот же самый ПК, на котором запущен сервер БД)
Клиенты 2,3,4 Windows 95 486 DX2-66/16 MB RAM

Об удаленном клиенте с использованием DCOM

В принципе можно использовать не OLEnterprise, а непосредственно технологию DCOM (Distributed Component Object Model) корпорации Microsoft. Не вдаваясь в теоретические подробности использования DCOM, отметим, что использование этой технологии для запуска серверов приложений возможно лишь при условии наличия первичного контроллера домена в сети и выбранной на рабочих станциях установки User Level Access Control на странице Access Control раздела Network панели управления Windows (это необходимо для переноса с контроллера домена списка пользователей для разрешения им доступа к серверу приложений). Помимо этого, сервер приложений может быть доступен для клиентских приложений, если только он выполняется под управлением Windows NT, но не Windows 95.

Отметим также, что сведения о сервере приложений должны быть в реестре клиента (этого можно добиться, например, путем запуска сервера приложений непосредственно на рабочей станции с ключом /regserver, если, конечно, ресурсы рабочей станции позволяют это сделать). После этого следует внести изменения в реестр так, чтобы зарегистрированный таким образом OLE-объект воспринимался не как локальный, а как удаленный объект. Это можно сделать как отредактировав реестр вручную, так и с помощью утилиты конфигурации DCOM, указав явно, на каком компьютере запускается сервер приложений (запустив эту утилиту на рабочей станции, содержащей клиентское приложение), и кто из пользователей имеет право его запускать (на компьютере, содержащем сервер приложений).

Примеры сервера и клиента, описанные в начале статьи, были выполнены и с использованием DCOM (без OLEnterprise). Характеристики использованных ПК для этого примера представлены в табл.2.

Таблица 2. Технические характеристики использованных ПК и ПО при соединении клиента и сервера приложений с помощью DCOM

Компоненты распределенной системы ПО ПК
Сервер БД Windows NT Server 4.0 + Oracle Workgroup Server 7.2 (Trial 90-day version) for Windows NT Pentium-133/32 MB RAM
Сервер приложений Windows Nt Server 4.0 Pentium-133/32 MB RAM (это тот же самый ПК, на котором запущен сервер БД)
Клиенты 1,2,3 Windows 95 Pentium-120/16 MB RAM

Удаленный клиент с использованием ActiveForm

Как было сказано выше, наличие "тонкого" клиента не только снижает требования к ресурсам рабочей станции, но и упрощает конфигурацию программного обеспечения для них (для работы такого клиента требуется лишь файл dbclient.dll размером 156 Кб из комплекта поставки Delphi 3.0 Client/Server Suite). Следствием этого является возможность осуществлять поставку таких приложений не путем создания обычного дистрибутива, а через intranet (или Internet, если говорить об информационной системе предприятия с удаленными филиалами), используя Web-сервер в качестве источника очередной версии приложения и Web-броузер в качестве средства его установки. При этом существует возможность выполнения такого приложения (если оформить его не как исполняемый файл, а как компонент ActiveX) непосредственно в броузере, используя тег <OBJECT>, поддерживаемый MS Internet Explorer 3.0 и 4.0.

Для распространения такого "тонкого" клиента следует иметь в сети какой-нибудь Web-сервер (например, Personal Web Server для Windows 95 или Internet Information Server для Windows NT).

Для создания "тонкого" клиента в виде ActiveX следует в репозитарии объектов Delphi выбрать страницу ActiveX и пикторамму ActiveForm.

Рис.9. Выбор ActiveForm из репозитория объектов
Рис.10. Создание нового компонента ActiveX для показа в броузере

После этого автоматически будет предложено создать ActiveX Library (файл с расширением OCX). Помимо главной формы приложения, на которой располагаются интерфейсные элементы (подобные, например, тем, что были использованы в предыдущем примере), следует создать модуль данных с необходимыми компонентами для доступа к данным..

Рис.11. "Тонкий" клиент, реализованный как ActiveForm

Отметим, что обработчик события для кнопки "О программе" отличается от стандартного: в модуле, свзанном с ActiveForm, имеется набор сгенерированных автоматически процедур и функций (можно найти их в исходном тексте соответствующего модуля), одну из которых мы и использовали.

procedure TMyAXF.Button1Click(Sender: TObject);

begin

AboutBox;

end;

Как показывает практика, в подобных формах можно использовать почти все интерфейсные элементы, содержащиеся в палитре компонентов Delphi, за исключением главного меню. Возможна также генерация дополнительных форм (отображаемых уже не внутри броузера, а отдельно от него).

После того как форма спроектирована, следует установить опции для переноса будущего ActiveX на Web-сервер. Для этой цели следует выбрать пункт меню Project /Web Deployment Options... и заполнить соответствующую диалоговую панель, указав в строке Target Dir каталог, в который следует переносить файлы, распространяемые через Internet, с точки зрения администратора Web-сервера, а в качестве URL - этот же каталог с точки зрения пользователя броузера, соединившегося с Web-сервером (как правило, имена, видимые пользователю извне Web-сервера, и администратору сервера, не совпадают). В строке

HTML dir следует указать, где лежит файл со ссылкой на ActiveForm.

Рис.12. Установка параметров поставки ActiveX через Internet

При распространении библиотек OCX через Internet рекомендуется использовать сжатие их в файлы с расширением *.cab, так как это уменьшает время их загрузки.

Если для функционирования клиентского приложения требуется файл dbclient.dll (или какие-либо другие файлы), следует указать их в закладке Additional Files.

Опция Include File Version Number необходима для того, чтобы своевременно обновлять версию созданного ActiveX, если произошло ее обновление на сервере.

Для переноса созданного OCX-файла на Web-сервер следует выбрать опцию Project /Web Deploy. При этом будет создан соответствующий CAB-файл и HTML-страница с минимальным набором тегов. В дальнейшем можно отредактировать полученную страницу.

После создания и переноса CAB-файла и Web-страницы на Web-сервер можно открыть эту страницу в броузере.

Следует обратить особое внимание на то, что по умолчанию уровень безопасности броузера является минимальным, а в этом случае полученный по сети элемент ActiveX будет просто проигнорирован броузером без выдачи какого бы то ни было сообщения. Если же выбран средний или минимальный уровень безопасности броузера, полученный по сети компонент будет зарегистрирован в реестре Windows (в этом можно убедиться, попытавшись найти имя формы в редакторе реестра), а соответствующий файл OCX хранится в каталоге для кэширования сгружаемых компонентов

Рис.13. Сведения о зарегистрированной библиотеке OCX в редакторе реестра

После открытия форма будет видна в броузере (рис.14). Можно убедиться, что все ее интерфейсные элементы работают так же, как и интерфейсные элементы в обычном приложении.

Рис.14. Web-страница с элементом ActiveX - "тонким" клиентом

Технические характеристики ПК, использованных для данного примера, приведены в табл. 3 (локальный вариант) и табл.4 (сетевой вариант).

Технические характеристики использованных ПК и ПО (локальный вариант трехзвенной системы с ActiveForm в качестве "тонкого" клиента)

Компоненты системы ПО ПК
Сервер БД Personal Oracle for Windows 95 (90-дневная trial-версия) Pentium-120/32 MB RAM
Сервер приложений Сервер приложений, созданный перед этим в первом примере Pentium-120/32 MB RAM (это тот же самый ПК, на котором запущен сервер БД)
Web-сервер Microsoft Personal Web Server for Windows 95
- ''-
Web-броузер Microsoft Internet Explorer 3.01 for Windows 95
-''-
Технические характеристики использованных ПК и ПО (сетевой вариант трехзвенной системы с ActiveForm в качестве "тонкого" клиента)
Компоненты распределенной системы ПО ПК
Сервер БД Windows NT Server 4.0 + Oracle Workgroup Server 7.2 for Windows NT (90-дневная trial-версия) Pentium-133/32 MB RAM
Сервер приложений Windows NT Server 4.0 Pentium-133/32 MB RAM (это тот же самый ПК, на котором запущен сервер БД)
Клиенты Windows 95 Pentium-120/16 MB RAM
Созданный нами сервер приложений является клиентом серверной СУБД. Отметим, что подобные приложения можно создавать и с локальными БД, обеспечивая их частичную обработку на сервере приложений.

Несколько слов о реализации сервера как многопоточного приложения. Если при создании сервера выбрана опция Multiple Instanse, каждый клиент на сервере может запустить свой процесс. Если же при создании сервера была выбрана опция Single Instanse, то каждый клиент может в рамках единого процесса создавать свой поток. В этом случае рекомендуется использовать при создании сервера компонент TSession со значением AutoSessionName, равным True, так, чтобы потоки, созданные разными клиентами, не использовали одну и ту же сессию и не мешали друг другу при сбоях.

В заключение хотелось бы отметить некоторые особенности Delphi 3.01, связанные с реализацией многозвенных приложений. В палитре компонентов этой версии продукта имеется новый компонент TMidasConnection, который может быть использован вместо TRemoteServer. Если TRemoteServer предназначен главным образом для доступа к серверам приложений посредством DCOM, TMidasConnection обладает свойством ConnectType, позволяющим определить, каким образом осуществляется соединение - посредством DCOM, сокетов TCP/IP или OLEnterprise.

Еще одной приятной особенностью новой версии является автоматическая установка параметров HTML-тега <OBJECT> так, чтобы размер изображения ActiveX в броузере соответствовал размерам формы (в прежней версии требовалась ручная правка генерируемой Web-страницы).

Автор выражает признательность Сергею Орлику за некоторые полезные идеи, в частности, идею использования ActiveForm для создания "тонкого" клиента, а также Андрею Брындину (АзовИмпекс) за идею создания многопоточного сервера.

Координаты автора


Interface Ltd.