Для создания сервера приложений, предоставляющего
Для создания сервера приложений, предоставляющего доступ к данным, нам потребуются какая-либо серверная СУБД, клиентом которой будет данный сервер приложений, и тестовые таблицы, которые будут перенесены на сервер баз данных. В рассмотренных ниже примерах используется база данных DBDEMOS, но в общем случае это может быть любая СУБД, в том числе серверная.
Создание CORBA-сервера начнем с создания обычной формы (можно небольшого размера, так как основное ее назначение - быть индикатором запущенного сервера приложений) со значением свойства FormStyle, равным fsStayOnTop (рис. 1), чтобы не потерять это окно среди других открытых окон.
Рис. 1. Главная форма сервера доступа к данным
Можно разместить ее где-нибудь в углу экрана. Появление на экране главной формы в общем случае не является обязательным. Тем не менее, коль скоро она создана, поместим на нее компонент TLabel и установим значение его свойства Caption равным "0" (в дальнейшем в этой метке будет отображаться число подключенных к серверу клиентов).
Сразу же создадим связанную с этой формой процедуру изменения значения счетчика подключений:
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Label1: TLabel; private FCount: Integer; { Private declarations } public procedure UpdateCount(Incr: Integer); { Public declarations } end;
var Form1: TForm1;
implementation
uses serv2;
{$R *.DFM}
{ TForm1 }
procedure TForm1.UpdateCount(Incr: Integer); begin FCount := FCount+Incr; Label1.Caption:= IntToStr(FCount) ; end;
end.
Далее из репозитария объектов (доступ к которому осуществляется выбором пункта меню File/New…) со страницы New следует выбрать объект CORBA Data Module (рис. 2).
Рис. 2. Выбор удаленного модуля данных из репозитария объектов
CORBA Data Module имеет принципиальное отличие от обычного модуля данных, заключающееся в том, что он представляет собой объект, обладающий CORBA-интерфейсами, доступными извне.
Создание CORBA Data Module начинается с запуска эксперта CORBA Data Module Wizard, в котором определяется, в частности, имя класса, под которым CORBA-объект - экземпляр данного класса - может быть опознан запрашивающими его приложениями (рис. 3):
Рис. 3. Выбор имени класса для удаленного модуля данных
Параметр Instancing указывает, сколько экземпляров данного класса может быть создано CORBA-сервером. Значение Instance-per-Client, используемое по умолчанию и выбранное нами в данном случае, означает, что один запущенный экземпляр сервера может создать несколько экземпляров удаленного модуля данных - по одному на каждого клиента. Значение Shared Instance означает, что один экземпляр удаленного модуля данных обслуживает несколько клиентов (это наиболее часто встречающаяся модель обработки данных в CORBA) . В этом случае следует создавать приложение так, чтобы модуль данных не хранил данные, связанные с конкретным клиентом (пример такого кода содержится в статье, посвященной созданию объектов Microsoft Transaction Server).
Параметр Threading Model указывает на то, поддерживает ли наш модуль данных многопоточность. Значение Single-threaded означает, что каждый экземпляр объекта обрабатывает в данный момент времени только один запрос клиента, поэтому обращение к данным, содержащимся в этом объекте (свойствам и др.) является безопасной операцией. Однако в этом случае следует предусматривать защиту от коллизий, связанных с модификацией глобальных переменных или объектов. Значение Multi-threaded означает, что каждое соединение, инициированное клиентом, обслуживается в отдельном потоке. В этом случае следует заботиться не только о глобальных переменных, но и о возможных коллизиях, связанных с одновременным обращением к данным объекта из разных потоков.
В данном случае можно оставить значение Single Threaded.
Далее в созданный удаленный модуль данных поместим два компонента TTable, свойство DatabaseName которых установим равным DBDEMOS, а имена равными CLIENTS.DBF (Table1) и HOLDINGS.DBF (Table2). Свойство Active этих компонентов TTable не обязательно устанавливать равным True (они будут автоматически открыты при обращении клиента к данному серверу приложений). Добавим также компонент TDataSourse и свяжем его с компонентом Table1 (рис. 4).
Рис. 4. Содержимое CORBA Data Module
В данном случае мы поместили компонент TDatabase на главную форму, а не в модуль данных. Это означает, что в этом случае все пользователи данного сервера будут использовать одно и то же соединение с базой данных и, соответственно, регистрироваться под именем одного и того же пользователя. Если такое решение неприемлемо, можно поместить его и в модуль данных. В этом случае туда же следует поместить и компонент TSession и позаботиться о разных именах пользовательских сессий во избежание конфликтов между ними.
Затем установим связь Master-Detail между таблицами (в данном случае по общему полю ACCT_NBR, для чего следует выбрать соответствующий индекс).
Далее из контекстного меню компонента Table1 нужно выбрать опцию:
Export Table1 from data module
Выбор этой опции приведет к тому, что в интерфейс, предоставляемый удаленным модулем данных, будут добавлены свойства и методы для работы с компонентами доступа к данным. В этом случае мы получим CORBA-объект, хранящий данные, связанные с конкретным клиентом, что вполне допустимо в случае, когда параметр Instancing имеет значение Instance-per-Client. В случае же, если этот параметр имеет значение Shared Instance, выбирать опцию экспорта из меню не следует, так как такой CORBA-объект не должен хранить никаких данных, связанных с конкретным клиентом (такие объекты называются stateless objects). В этом случае обычно создается метод, реализующий содинение с базой данных, открытие нужной таблицы, передачу данных клиенту, закрытие таблицы и разрыв соединения с базой данных (так называемый stateless code).
Проконтролировать наличие в интерфейсе удаленного модуля данных свойств и методов для доступа клиента к компонентам доступа к данным можно, просмотрев соответствующую библиотеку типов (рис. 5):
Рис. 5. Содержимое удаленного модуля данных
Находясь в редакторе библиотеки типов, нажмем кнопку экспорта ее в файл описания интерфейса CORBA IDL - этот файл нам пригодится в дальнейшем.
Теперь включим ссылку на главную форму приложения в текст модуля, связанного с удаленным модулем данных и создадим обработчики событий, связанные с созданием и уничтожением удаленного модуля данных:
procedure Tcrb1.crb1Create(Sender: TObject); begin Form1.UpdateCount(1); end;
procedure Tcrb1.crb1Destroy(Sender: TObject); begin Form1.UpdateCount(-1); end;
Далее следует сохранить проект и скомпилировать приложение.
Отметим, что для того, чтобы клиентское приложение имело доступ к CORBA-серверу, недостаточно иметь запущенный экземпляр сервера, даже если разработка клиента производится на том же самом компьютере. CORBA, в отличие от COM, не делает различий между локальным и удаленным сервером; и в том, и в другом случае требуется запуск сервиса, предоставляющего доступ к серверу. В случае реализации CORBA, предложенной Visigenic, он называется Visibroker Smart Agent.
Можно легко объяснить, почему в случае CORBA не делается различий между локальным и удаленным сервером. COM есть не только технология распределенных вычислений, но и способ организации разделения функций между приложениями и библиотеками, составляющий в значительной степени основу самой операционной системы Windows. Естественно, что механизмы, осуществляющие поиск локальных COM-объектов и инициирование запуска COM-серверов, эти объекты реализующих, интегрированы в операционную систему и используют регистрационную базу данных самой операционной системы - реестр Windows - для поиска этих реализаций. Вообще говоря, и механизмы удаленного доступа к COM-серверам также содержатся в Windows NT и практически не отличаются от механизмов доступа к серверам локальным, просто они требуют соответствующих настроек, связанных главным образом с соображениями элементарной безопасности.
CORBA же есть, по существу, межплатформная технология. Требование поддержки многих платформ, естественно, не может быть выполнено, если в технологии распределенных вычислений используется какой-либо механизм, специфический для конкретной платформы (например, использование реестра - ведь его нет в других операционных системах). Следовательно, CORBA не может использовать и механизмы доступа к серверам и сервисам, доступные COM, так как они специфичны для Windows.Иные же способы доступа к серверам не содержатся в операционных системах и, следовательно, требуют наличия сервисов, предоставляющих такой доступ.
Итак, прежде чем приступить к разработке клиентского приложения, нужно обязательно запустить Smart Agent (он устанавливается одновременно с Delphi 4 Client/Server Suite) и лишь потом запустить скомпилированный сервер (желательно непосредственно из Windows).
| >>