Создание CORBA-сервера
Усложним задачу, добавив в проект новый сервер для CORBA-соединения. Его создание как две капли воды похоже на изготовление обычного сервера, о чем мы только что говорили. Вся разница состоит лишь в том, что на начальном этапе вместо мастера Remote Data Module мы запускаем мастер New?Multitier?CORBA Data Module. Компоненты доступа к данным и их связывание точно такое же. Модуль формы сервера сохраните как CORBAMain.pas, имя формы (свойство Caption) установите как MsgForm, ее заголовок (свойство Caption) — «Client Messages», а сам проект должен быть сохранен как CORBA_RDM_ Server.dpr. Точно так же в форму нужно положить компонент TProgressBar. Не забудьте включить опцию проекта Build with runtime packages.
Теперь о различиях. Они проявятся, как только вы запустите мастер CORBA Data Module. Поле Class Name вам уже знакомо, в него следует ввести имя CORBA_RDM. Зато ранее мы не сталкивались с полями Instancing и Threading Model. Если вы хотите, чтобы для каждого клиентского вызова создавался новый экземпляр удаленного модуля данных, следует установить в поле Instancing опцию Instance-per-client. Если установить опцию Shared Instance, один экземпляр модуля будет обслуживать запросы от разных клиентов (то, что нужно нам). В поле Threading Model нужно указывать, должен ли модуль обслуживать несколько вызовов одновременно (Multithreaded) или по одному вызову за раз (Single-threaded), что мы с вами и сделаем.
Сохраним исходный текст в файле с именем CORBA_RDM_Impl.pas и откомпилируем проект. В отличие от обычного удаленного модуля данных, аналогичный модуль на основе CORBA не требует регистрации. Если же вы хотите автоматически запускать подобный CORBA-сервер, то следует обратиться к документации по Inprise VisiBroker к разделу, посвященному OAD.
Исходные тексты CORBA-сервера приведены в листинге 1.
Листинг 1
CORBA-сервер
Файл CORBA_RDM_Impl.dfm
object CORBA_RDM: TCORBA_RDM
OldCreateOrder = False
Left = 65
Top = 197
Height = 480
Width = 696
object DataSetProvider1: TDataSetProvider
DataSet = IBQuery1
Constraints = True
AfterGetRecords =
DataSetProvider1AfterGetRecords
Left = 45
Top = 20
end
object IBDatabase1: TIBDatabase
Connected = True
DatabaseName = ?
D:BorlandInterbaseexamplesdatabase
Employee.gdb?
Params.Strings = (
?user_name=SYSDBA?
?password=masterkey?)
LoginPrompt = False
DefaultTransaction = IBTransaction1
IdleTimer = 0
SQLDialect = 1
TraceFlags = []
Left = 45
Top = 105
end
object IBTransaction1: TIBTransaction
Active = True
DefaultDatabase = IBDatabase1
Left = 165
Top = 110
end
object IBQuery1: TIBQuery
Database = IBDatabase1
Transaction = IBTransaction1
Active = True
CachedUpdates = False
SQL.Strings = (
?select CUST_NO, SALES_REP, ORDER_DATE, PAID,
QTY_ORDERED, TOTAL_? +
?VALUE from SALES?)
Left = 45
Top = 200
object IBQuery1CUST_NO: TIntegerField
FieldName = ?CUST_NO?
Required = True
end
object IBQuery1SALES_REP: TSmallintField
FieldName = ?SALES_REP?
end
object IBQuery1ORDER_DATE: TDateTimeField
FieldName = ?ORDER_DATE?
Required = True
end
object IBQuery1PAID: TIBStringField
FieldName = ?PAID?
Size = 1
end
object IBQuery1QTY_ORDERED: TIntegerField
FieldName = ?QTY_ORDERED?
Required = True
end
end
end
Файл CORBA_RDM_Impl.pas
unit CORBA_RDM_Impl;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls,
Forms, Dialogs,
ComObj, VCLCom, StdVcl, DataBkr,
CorbaRdm, CorbaObj,
CORBA_Server_TLB, Db, IBCustomDataSet,
IBQuery, IBDatabase
Provider,
CORBAMain;
type
TCORBA_RDM = class(TCorbaDataModule,
ICORBA_RDM)
DataSetProvider1: TDataSetProvider;
IBDatabase1: TIBDatabase;
IBTransaction1: TIBTransaction;
IBQuery1: TIBQuery;
IBQuery1CUST_NO: TIntegerField;
IBQuery1SALES_REP: TSmallintField;
IBQuery1ORDER_DATE: TDateTimeField;
IBQuery1PAID: TIBStringField;
IBQuery1QTY_ORDERED: TIntegerField;
procedure
DataSetProvider1AfterGetRecords(Sender:
TObject;
var OwnerData: OleVariant);
private
{ Private declarations }
public
{ Public declarations }
protected
{ Protected declarations }
end;
var
CORBA_RDM: TCORBA_RDM;
implementation
{$R *.DFM}
uses CorbInit, CorbaVcl;
procedure TCORBA_RDM
.DataSetProvider1AfterGetRecords(Sender:
TObject;
var OwnerData: OleVariant);
begin
with MsgForm.ProgressBar1 do
begin
If Position < Max then
StepIt
else
Position := 0;
end;
end;
initialization
TCorbaVclComponentFactory
.Create(?CORBA_RDMFactory?,
?CORBA_RDM?, ?IDL:CORBA_Server
/CORBA_RDMFactory:1.0?,
ICORBA_RDM,
TCORBA_RDM, iSingleInstance,
tmSingleThread);
end.Создание клиента
Наконец мы добрались до кульминационного момента — создания программы-клиента (исходные тексты приведены в листинге 2).
Создадим новый проект и, как обычно, включим опцию проекта Build with runtime packages. Проект сохраним под именем Client.dpr, а главное окно программы будет носить имя ClientForm. Модуль окна сохраняется в файле ClientFormUnit.pas.
Интерфейс пользователя сделать несложно: поместим в главную форму компонент TCoolBar и установим его свойство AutoSize в значение True. Внутрь TCoolBar поместим компоненты TDBNavigator (для перемещения по данным) и TComboBox (для переключения между различными типами соединений). В раскрывающемся списке отредактируем свойство Items, определяющее пункты выбора. Таких пунктов должно быть три: DCOMConnection, SocketConnection и CorbaConnection.
В соответствии с традицией все компоненты, заведующие работой с данными, следует вынести в отдельный модуль. Поэтому командой New...?New? Data Module создадим подобный модуль данных и сохраним его под именем ClientDM, его свойство Name установим как dm. Внутрь полученного модуля кладутся следующие компоненты: TClientDataSet, TDataSource, TsocketConnection, TDCOMConnection и TCorbaConnection. Настройка первого из них очень проста. Его свойство ProviderName должно указывать на компонент DataSetProvider1. Еще важно, чтобы свойству Active было присвоено False, т. е. клиент должен быть отключен от сервера. Компонент TDataSource своим свойством DataSet будет указывать на TClientDataSet.
Теперь поработаем с компонентами соединения. TDCOMConnection будет носить имя DCOMGate, а его свойство ComputerName однозначно определяет имя компьютера, где запущен сервер MIDAS-приложения. Так же подстраиваем свойство ServerName. Delphi сам предложит для него правильное значение. Свойство Connected устанавливается в отключенное положение (должно быть False). Аналогично производится настройка TSocketConnection, только его имя будет SocketGate, а вместо свойства ComputerName настраивается Host.
С компонентом TCorbaConnection возни чуть больше. Для его корректного функционирования нужно присвоить свойству RepositaryId правильное значение, ссылающееся на удаленный модуль CORBA. Его можно найти в исходных текстах удаленного модуля данных CORBA_RDM. Разыщите строчку с вызовом TCorbaVclComponentFactory.Create(). Его третий параметр и будет правильным значением для RepositaryId.
Остается подстроить свойство DataSource компонентов TDBNavigator и TDBGrig так, чтобы оно указывало на dm.DataSource1, и откомпилировать проект.
Исходные тексты программы-клиента вы найдете в листинге 2.Листинг 2
Программа-клиент
Файл ClientFormUnit.dfm
object ClientForm: TClientForm
Left = 143
Top = 192
Width = 632
Height = 381
Caption = ?Universal MIDAS Client?
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = ?MS Sans Serif?
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 120
TextHeight = 16
object CoolBar1: TCoolBar
Left = 0
Top = 0
Width = 624
Height = 29
AutoSize = True
Bands = <
item
Control = DBNavigator1
ImageIndex = -1
Width = 273
end
item
Break = False
Control = ComboBox1
ImageIndex = -1
MinHeight = 24
Width = 345
end>
object ComboBox1: TComboBox
Left = 284
Top = 0
Width = 332
Height = 24
Style = csDropDownList
ItemHeight = 16
TabOrder = 0
OnChange = ComboBox1Change
Items.Strings = (
?DCOMConnection?
?SocketConnection?
?CorbaConnection?)
end
object DBNavigator1: TDBNavigator
Left = 9
Top = 0
Width = 260
Height = 25
DataSource = dm.DataSource1
TabOrder = 1
end
end
object DBGrid1: TDBGrid
Left = 0
Top = 29
Width = 624
Height = 320
Align = alClient
DataSource = dm.DataSource1
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -13
TitleFont.Name = ?MS Sans Serif?
TitleFont.Style = []
end
end
Файл ClientDM.dfm
object dm: Tdm
OldCreateOrder = False
Left = 58
Top = 179
Height = 480
Width = 696
object DCOMGate: TDCOMConnection
ServerGUID =
?{CEFB8363-867D-11D3-9531-008048DEAFF9}?
ServerName = ?RDM_Server.RDM?
ComputerName = ?Dimos?
Left = 55
Top = 10
end
object SocketGate: TSocketConnection
ServerGUID =
?{CEFB8363-867D-11D3-9531-008048DEAFF9}?
ServerName = ?RDM_Server.RDM?
Host = ?Dimos?
Left = 145
Top = 10
end
object CorbaGate: TCorbaConnection
RepositoryId = ?CORBA_Server/CORBA_RDM?
Left = 230
Top = 10
end
object DataSource1: TDataSource
DataSet = ClientDataSet1
Left = 55
Top = 150
end
object ClientDataSet1: TClientDataSet
Aggregates = <>
Params = <>
ProviderName = ?DataSetProvider1?
Left = 55
Top = 85
end
end
Файл ClientFormUnit.pas
unit ClientFormUnit;
interface
uses
Windows, Messages, SysUtils,
Classes, Graphics, Controls,
Forms, Dialogs,
ExtCtrls, DBCtrls, StdCtrls,
ToolWin, ComCtrls, Grids,
DBGrids, ClientDM,
DBClient;
type
TClientForm = class(TForm)
CoolBar1: TCoolBar;
ComboBox1: TComboBox;
DBNavigator1: TDBNavigator;
DBGrid1: TDBGrid;
procedure ComboBox1Change(Sender:
TObject);
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure Reconnect;
end;
var
ClientForm: TClientForm;
LastConnection: Integer;
Connections: array[0..2] of
^TCustomRemoteServer;
implementation
{$R *.DFM}
procedure TClientForm
.ComboBox1Change(Sender: TObject);
begin
if LastConnection <> ComboBox1
.ItemIndex then Reconnect;
end;
procedure TClientForm.Reconnect;
begin
// Отключиться от удаленного сервера
Connections[LastConnection].Connected
:= False;
LastConnection := ComboBox1.ItemIndex;
// Подключиться к удаленному серверу
dm.ClientDataSet1.Close;
dm.ClientDataSet1.RemoteServer
:= Connections
[LastConnection]^;
dm.ClientDataSet1.Open;
Connections[LastConnection].Connected
:= True;
dm.ClientDataSet1.Refresh;
// Показать тип соединения
ComboBox1.ItemIndex := LastConnection;
end;
procedure TClientForm.FormShow(Sender
: TObject);
begin
// Заполнить массив указателей на
компоненты соединения
Connections[0] := @dm.DCOMGate;
Connections[1] := @dm.SocketGate;
Connections[2] := @dm.CorbaGate;
// Установить индекс соединения на DCOM
LastConnection := 0;
ComboBox1.ItemIndex := LastConnection;
Reconnect;
end;
end. Как запустить MIDAS-приложение
Для обеспечения работы систем, выполненных по технологии MIDAS, могут потребоваться дополнительные утилиты. Так, чтобы стало действовать соединение на основе CORBA, следует активизировать программу Smart Agent из пакета VisiBroker. Соединение через сокеты установится после запуска SCKTSRVR.EXE каталога BIN пакета Delphi. Дополнительных действий не требует лишь соединение по протоколу DCOM.
Запустив наш пример, попробуйте переключиться с одного соединения на другое. Каждый раз при выборке удаленных данных вы увидите, как увеличивается значение индикатора прогресса (рис. 1).
![]() |
| Рис. 1 |
* * *
Напоследок маленькое напоминание. Не забывайте о том, что MIDAS — высокотехнологичный информационный продукт и подпадает под особую лицензионную политику. Свяжитесь с вашим поставщиком Delphi 5, чтобы узнать об этом поподробнее.

