Удаленный модуль данных для сервера Автоматизации
Для создания удаленного модуля данных TRemoteDataModule используется Репозиторий Delphi (команда File | New | Other). Значок класса TRemoteDataModuie находится на странице Multitier (см. рис. 20.3). Перед созданием экземпляра удаленного модуля данных появляется диалоговое окно (рис. 21.1), в котором необходимо предустановить три параметра.
Рис 21.1. Мастер создания удаленного модуля данных TRemoteDataModule
Строка CoClass Name должна содержать имя нового модуля данных, которое будет также использовано для именования нового класса, создаваемого для поддержки нового модуля данных.
Список Instancing позволяет задать способ создания модуля данных.
- Internal — модуль данных обеспечивает функционирование лишь внутреннего сервера Автоматизации.
- Single Instance — для каждого клиентского соединения создается собственный экземпляр удаленного сервера Автоматизации в собственном процессе.
- Multiple Instance — для каждого клиентского соединения создается собственный экземпляр удаленного сервера Автоматизации в одном общем процессе.
Список Threading Model задает механизм обработки запросов клиентов.
- Single — поток запросов клиентов обрабатывается строго последовательно.
- Apartment — модуль данных одновременно обрабатывает один запрос. Однако если DLL для выполнения запросов создает экземпляры СОМ объектов, то для запросов могут создаваться отдельные нити, в которых обработка ведется параллельно.
- Free — модуль данных может создавать нити для параллельного выполнения запросов.
- Both — аналогична модели Free, за исключением того, что все ответы клиентам возвращаются строго один за другим.
- Neutral — запросы клиентов могут направляться модулям данных в нескольких нитях одновременно. Используется только для технологии СОМ+.
При создании нового удаленного модуля данных создается специальный класс — наследник класса TRemoteDataModule. И фабрика класса на основе класса TComponentFactory
Примечание
Класс TComponentFactory представляет собой фабрику класса для компонентов Delphi, инкапсулирующих интерфейсы. Поддерживает интерфейс IClass Factory.
Создадим, например, удаленный модуль данных simpleRDM. В мастере создания модуля данных в качестве способа создания выберем Single Instance, a Free — как модель обработки запросов.
Листинг 21.1. Исходный код нового удаленного модуля данных и его фабрики класса
type
TSimpleRDM = class(TRemoteDataModuie, ISimpleRDM)
private
( Private declarations }
protected
class procedure UpdateRegistry(Register: Boolean;
const Classic,
ProgID: string);
override;
public
{ Public declarations }
end;
implementation
{$R *.DFM}
class procedure TSimpleRDM.UpdateRegistry(Register: Boolean;
const
ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, Classic, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end
else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;
initialization
TComponentFactory.Create(ComServer, TSimpleRDM,
Class_SimpleRDM, ciMultilnstance, tmApartment);
end.
Обратите внимание, что параметры модуля данных, заданные при создании, использованы в фабрике класса TComponentFactory в секции initialization.
Примечание
Фабрика класса TComponentFactory обеспечивает создание экземпляров компонентов Delphi, поддерживающих использование интерфейсов.
Метод класса UpdateRegistry создается автоматически и обеспечивает регистрацию и аннулирование регистрации сервера Автоматизации. Если параметр Register имеет значение True, выполняется регистрация, иначе — отмена регистрации.
Разработчик не должен использовать этот метод, т. к. его вызов осуществляется автоматически.
Одновременно с модулем данных создается и его интерфейс — потомок интерфейса IAppServer. Его исходный код содержится в библиотеке типов проекта сервера приложения. Для удаленного модуля данных simpleRDM созданный интерфейс isimpleRDM представлен в листинге 21.2. Для удобства из листинга удалены автоматически добавляемые комментарии.
Листинг 21.2. Вновь созданная библиотека типов для сервера приложения с исходным кодом интерфейса удаленного модуля данных
LIBID_SimpleAppSrvr: TGUID='(93577575-OF4F-43B5-9FBE-A5745128D9A4}';
IID_ISimpleRDM: TGUID = '{Е2СВЕВСВ-1950-4054-В823-62906306Е840}'; CLASS_SimpleRDM: TGUID = '{DB6A6463-5F61-485F-8F23-EC6622091908}' ;
type
ISimpleRDM = interface;
ISimpleRDMDisp = dispinterface;
SimpleRDM = ISimpleRDM;
ISimpleRDM = interface(lAppServer)
['{E2CBEBCB-1950-4054-B823-62906306E840}']
end;
ISimpleRDMDisp = dispinterface
['{E2CBEBCB-1950-4054-B823-62906306E840}']
function AS_ApplyUpdates(const ProviderName: WideString; Delta: OleVariant; MaxErrors: Integer; out ErrorCount: Integer; var OwnerData: OleVariant): OleVariant; dispid 20000000; function AS_GetRecords(const ProviderName: WideString; Count: Integer; out RecsOut: Integer; Options: Integer; const CommandText: WideString; var Params: OleVariant; var OwnerData: OleVariant): OleVariant; dispid 20000001;
function AS_DataRequest(const ProviderName: WideString; Data: OleVariant): OleVariant; dispid 20000002;
function AS_GetProviderNames: OleVariant; dispid 20000003;
function AS_GetParams(const ProviderName: WideString;
var OwnerData: OleVariant): OleVariant; dispid 20000004;
function AS_RowRequest(const ProviderName: WideString; Row: OleVariant; RequestType: Integer; var OwnerData: OleVariant): OleVariant; dispid 20000005;
procedure AS_Execute(const ProviderName: WideString; const CommandText: WideString; var Params: OleVariant; var OwnerData: OleVariant);
dispid 20000006;
end;
CoSimpleRDM = class
class function Create: ISimpleRDM;
class function CreateRemote(const MachineName: string): ISimpleRDM;
end;
imp1ementation uses ComObj;
class function CoSimpleRDM.Create: ISimpleRDM;
begin
Result := CreateComObject(CLASS_SimpleRDM) as ISimpleRDM;
end;
class function CoSimpleRDM.CreateRemote(const MachineName: string): ISimpleRDM;
begin
Result := CreateRemoteComObject(MachineName, CLASS_SimpleRDM)
as ISimpleRDM;
end;
end.
Обратите внимание, что интерфейс ISimpleRDM является потомком интерфейса IAppServer, рассмотренного выше.
Так как удаленный модуль данных реализует сервер Автоматизации, дополнительно к основному дуальному интерфейсу ISimpleRDM автоматически создан интерфейс диспетчеризации isimpleRDMDisp. При этом для интерфейса диспетчеризации созданы методы, соответствующие методам интерфейса IAppServer.
Класс coSimpleRDM обеспечивает создание СОМ-объектов, поддерживающих использование интерфейса. Для него автоматически созданы два метода класса.
Метод
class function Create: ISimpleRDM;
используется при работе с локальным и внутренним сервером (in process).
Метод
class function CreateRemote(const MachineName: string): ISimpleRDM;
используется в удаленном сервере.
Оба метода возвращают ссылку на интерфейс ISimpleRDM.
Теперь, если проект с созданным модулем данных сохранить и зарегистрировать, он станет доступен в удаленных клиентских приложениях как сервер приложения.
После создания удаленный модуль данных становится платформой для размещения компонентов доступа к данным и компонентов провайдеров (см. гл. 20), которые, наряду с модулем данных, реализуют основные функции сервера приложения.