Другим фактором, приводящим к удорожанию эксплуатации информационной системы, является необходимость инсталляции и конфигурации BDE и клиентской части серверной СУБД, что нередко является весьма трудоемким процессом, особенно при большом количестве и неоднородном парке рабочих станций.
Выходом из этой ситуации является создание систем с так называемым "тонким" клиентом, в частности, с клиентом, не содержащим в своем составе BDE и клиентскую часть серверной СУБД. В этом случае функциональность, связанная с доступом к данным (а нередко и какая-либо иная функциональность), возлагается на другое приложение, называемое обычно сервером приложений, и являющееся клиентом серверной СУБД. В свою очередь, клиентские приложения обращаются не непосредственно к серверной СУБД посредством вызова функций клиентских API, а к серверу приложений, являющемуся для них источником данных, при этом собственно клиентская часть серверной СУБД и библиотеки типа BDE на рабочей станции, где используется такое клиентское приложение, присутствовать не обязаны. Вместо них используется одна-единственная динамически загружаемая библиотека dbclient.dll размером 154 Кб. Таким образом, созданная информационная система становится трехзвенной, а сервер приложений является средним звеном в цепи "тонкий клиент - сервер приложений - сервер баз данных" и, соответственно, относится к классу продуктов middleware.
Как может быть практически реализована данная технология? С одной стороны, с помощью набора компонентов и классов Delphi 3, обеспечивающих создание серверов приложений и клиентских частей, а, с другой стороны, с помощью MIDAS, позволяющего осуществлять запуск удаленных серверов приложений, осуществлять межреестровый обмен сведениями об OLE-серверах и оптимизировать нагрузку в случае использования нескольких серверов приложений. В данной статье будет рассмотрен простейший практический пример реализации подобной трехзвенной системы.
Создадим нового пользователя 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. После этого можно приступить к созданию простейшего сервера приложений, являющегося, с одной стороны, клиентом серверной СУБД, и, с другой стороны, сервером конечного пользовательского приложения, которое становится при этом так называемым "тонким" клиентом.
Username=user1Password = user1
Далее из репозитария объектов (доступ к которому осуществляется выбором пункта меню File/New…) со страницы New следует выбрать объект Remote Data Module (рис.2).
Remote Data Module имеет принципиальное отличие от обычного DataModule, заключающееся в том, что объекты, помещенные в него, могут иметь COM-интерфейс.
Создание Remote Data Module начинается с запуска эксперта Remote Dataset Wizard, в котором определяется, в частности, имя класса, под которым данный сервер приложений (он же OLE-сервер) будет зарегистрирован в реестре (рис.3):
Далее в созданный удаленный модуль данных поместим два компонента TTable, связанных с компонентом Database1 и указывающих на только что созданные таблицы CLIENTS и HOLDINGS, а также два компонента TProvider. Установим значения свойств DataSet компонентов TProvider равными именам соответствующих компонентов TTable. Установим связь master/detail между таблицами по полю ACCT_NBR. Откроем таблицы (рис. 4)
Далее из контекстного меню компонентов TTable и TProvider нужно выбрать опции
Export MyProv2 from data module
Export Table1 from data module
Export Table2 from data module
Если теперь исследовать полученную библиотеку типов (Type library), можно обнаружить, что COM-объект, который будет создаваться при запуске данного приложения, обладает интерфейсом, осуществляющим доступ извне к компонентам MyProv1, MyProv2, Table1 и Table2. (рис. 5).
Далее следует сохранить проект и скомпилировать приложение.
Рекомендуется убедиться, что оно зарегистрировано в реестре под выбранным ранее именем. Если тем не менее по каким-либо причинам этого не произошло, следует запустить наше приложение-сервер с параметром /regserver. После этого проект следует закрыть.
Попробуем установить свойство ServerName компонента RemoteServer1 (выбрав его из выпадающего списка или введя вручную). После этого, если в реестре есть соответствующая запись, автоматически будет установлено значение свойства ServerGUID. При этом сервер приложений, созданный ранее, должен автоматически запуститься, о чем будет свидетельствовать появившаяся на экране его главная форма.
После этого можно установить нужные значения свойств ProviderName компонентов TClientDataSet, выбрав их из выпадающего списка (так как сервер приложений выбран, все его доступные через интерфейс свойства становятся видны в среде разработки). После этого можно установить связь master/detail между таблицами по общему полю ACCT_NBR.
Далее нужно установить значения свойства Active компонентов TClientDataSet равными True и связать интерфейсные элементы главной формы приложения с соответствующими полями таблиц, доступных через запущенный сервер приложений.
Теперь можно скомпилировать и запустить приложение. Отметим, что при запуске приложения из среды разработки с сервером приложений соединены два клиента - среда разработки и скомпилированное клиентское приложение. При желании можно с помощью утилиты SQL Monitor проследить, какие именно запросы созданный нами сервер приложений направляет серверу баз данных.
Данный пример был выполнен на ПК Pentium-120/32 МБ c ОС Windows 95 с использованием. Personal Oracle 7.2 for Windows 95 (90-дневная trial-версия)и Delphi 3.0. При этом во время отладки приложения был постоянно загружен MicrosoftWord 7.0.
Для использования OLEnterprise следует установить его полную версию (содержащую фабрику классов - Class Factory) на компьютер, на котором будет запущен сервер приложений, и Run-time-версию - на компьютер, содержащий приложение-клиент.
На компьютере, содержащем полную версию OLEnterprise, следует запустить приложение Business Object Broker, обеспечивающее соединение клиента с сервером и равномерное распределение нагрузки между серверами приложений, если их несколько. Далее следует запустить приложение Object Factory. Затем следует запустить Object Explorer - утилиту, предназначенную для межреестрового обмена сведениями о серверах приложений между компьютерами в сети. Далее следует найти созданный ранее сервер приложений среди полученного из реестра данного компьютера списка OLE-серверов и экспортировать его (иногда это называется публикацией объекта), выбрав в меню пункт Object/Export (рис.8). После этого OLE-сервер можно будет "увидеть" с удаленных компьютеров в сети как доступный для них объект.
На рабочей станции, где будет запущено приложение-клиент, следует запустить 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 |
Отметим также, что сведения о сервере приложений должны быть в реестре клиента (этого можно добиться, например, путем запуска сервера приложений непосредственно на рабочей станции с ключом /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 |
Для распространения такого "тонкого" клиента следует иметь в сети какой-нибудь Web-сервер (например, Personal Web Server для Windows 95 или Internet Information Server для Windows NT).
Для создания "тонкого" клиента в виде ActiveX следует в репозитарии объектов Delphi выбрать страницу ActiveX и пикторамму ActiveForm.
После этого автоматически будет предложено создать ActiveX Library (файл с расширением OCX). Помимо главной формы приложения, на которой располагаются интерфейсные элементы (подобные, например, тем, что были использованы в предыдущем примере), следует создать модуль данных с необходимыми компонентами для доступа к данным..
Отметим, что обработчик события для кнопки "О программе" отличается от стандартного: в модуле, свзанном с ActiveForm, имеется набор сгенерированных автоматически процедур и функций (можно найти их в исходном тексте соответствующего модуля), одну из которых мы и использовали.
procedure TMyAXF.Button1Click(Sender: TObject);Как показывает практика, в подобных формах можно использовать почти все интерфейсные элементы, содержащиеся в палитре компонентов Delphi, за исключением главного меню. Возможна также генерация дополнительных форм (отображаемых уже не внутри броузера, а отдельно от него).begin
AboutBox;
end;
После того как форма спроектирована, следует установить опции для переноса будущего ActiveX на Web-сервер. Для этой цели следует выбрать пункт меню Project /Web Deployment Options... и заполнить соответствующую диалоговую панель, указав в строке Target Dir каталог, в который следует переносить файлы, распространяемые через Internet, с точки зрения администратора Web-сервера, а в качестве URL - этот же каталог с точки зрения пользователя броузера, соединившегося с Web-сервером (как правило, имена, видимые пользователю извне Web-сервера, и администратору сервера, не совпадают). В строке
HTML dir следует указать, где лежит файл со ссылкой на ActiveForm.
При распространении библиотек 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 хранится в каталоге для кэширования сгружаемых компонентов
После открытия форма будет видна в броузере (рис.14). Можно убедиться, что все ее интерфейсные элементы работают так же, как и интерфейсные элементы в обычном приложении.
Технические характеристики ПК, использованных для данного примера, приведены в табл. 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 |
|
Компоненты распределенной системы | ПО | ПК |
Сервер БД | 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 для создания "тонкого" клиента, а также Андрею Брындину (АзовИмпекс) за идею создания многопоточного сервера.