Серверы и контроллеры автоматизации. Создание клиента для нотификационного сервера

   
На этом шаге мы рассмотрим алгоритм создания клиента для нотификационного сервера.

   
Теперь создадим новый проект для клиентского приложения с именем CliNote, выбрав в меню Delphi команду
File | New | Application. Сразу же следует оговориться, что этот проект обязательно надо сохранять в ином
каталоге, нежели каталог, в котором хранится код для сервера AutoServ. Причина - смешение версий файла
AutoServ_TLB, одна из которых хранится в каталоге с сервером, а другая - в каталоге $DELPHI\Imports.
Для корректной работы клиентского приложения необходима версия, которая будет храниться в каталоге $DELPHI\Imports.

   
Поместим на форму компоненты ТМеmо и TButton. Выберем команду Project | Import Type Library и в
списке появившегося диалогового окна выберем пункт AutoServ Library.


Рис.1. Импорт библиотеки типов сервера

   
Установим флажок Generate Component Wrapper и закроем окно щелчком на кнопке Install. После этого
Delphi задаст несколько вопросов, связанных с регистрацией нового компонента. Если все будет успешно
выполнено, то на странице ActiveX палитры компонентов появится значок класса TTest. Поместим его на форму.


Рис.2. Приложение на этапе разработки

   
Компонент TTest - это сгенерированный Delphi контейнер для сервера автоматизации. В нем во время
выполнения доступны все свойства и методы, которые ранее были определены на сервере в интерфейсе ITest.
Кроме того, на странице Events окна инспектора объектов можно увидеть названия методов нотификационного интерфейса -
OnTextChange и OnClose. Создавая обработчики этих событий, мы реализуем нотификациониый интерфейс на клиенте.
Как и в предыдущих проектах, вызов сервера будет осуществляться динамически. Реализуем следующий код для клиента:

type
  TForm1 = class(TForm)
.    .   .   .
  private
    IT: ITest;
.    .   .   .
  end;
.    .   .   .
implementation

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(IT) then
  begin
    IT := nil;
    Test1.Disconnect;
    Button1.Caption := 'Connect';
  end
  else
  begin
    Test1.Connect;
    IT := Test1.DefaultInterface as ITest;
    Button1.Caption := 'Disconnect';
  end;
end;

procedure TForm1.Test1Close(Sender: TObject);
begin
  IT := nil;
  Test1.Disconnect;
  Button1.Caption := 'Connect';
end;

procedure TForm1.Test1TextCahnge(Sender: TObject);
begin
  Memo1.Text := Test1.Text; 
end;

end.

Текст этого приложения можно взять здесь (5,5 Кб).

   
В секции private объявляется переменная IT: ITest, в которой будет храниться ссылка на интерфейс
СОМ-сервера. На самом деле, ссылка хранится в качестве значения свойства DefaultInterface класса TTest.
Однако, по-видимому, вследствие ошибки Delphi это свойство не инициализировано - при отсоединенном сервере там хранится значение,
не равное nil. В обработчике Button1Click мы подключаемся к серверу, если соединения с ним нет,
и наоборот, отсоединяемся, если соединение есть. При получении от сервера нотификации OnTextChange у сервера
запрашивается новый текст и помещается в компонент ТМеmо. При получении сообщения OnClose выполняется отсоединение от сервера.

   
Для тестирования проекта лучше запустить несколько экземпляров созданного приложения, соединиться с СОМ-сервером и попробовать
изменять содержимое компонента ТМеmо на сервере. Клиенты будут воспроизводить все изменения (рисунок 3.


Рис.3. Получение клиентами нотификаций от СОМ-сервера

   
Можно закрыть сервер щелчком на кнопке закрытия, и текст на кнопке клиента изменится на Connect, свидетельствуя об отсоединении от сервера.

   
Следует иметь в виду, что теоретически несколько клиентских приложений могут подключиться к одному интерфейсу для получения
нотификационных сообщений. Например, это возможно при использовании более "мягкого" метода - GetActiveObject вместо используемого
в CoTest.Create метода CreateComObject. В этом случае клиентскому приложению будет возвращена
ссылка на уже созданный интерфейс ITest. Для того чтобы можно было вызвать метод Advise интерфейса
IConnectionPoint, необходимо сделать перечисленные ниже изменения в сервере AutoServ.

  • В реализации метода Initialize класса TTest изменить флаг ckSingle на ckMulti.
  • В секции public класса TTest объявить предназначенное только для чтения свойство
    ConnectionPoint типа TConnectionPoint.
  • Для вызова метода нотификациониого интерфейса использовать, например, следующую конструкцию:
    procedure TForm1.Memo1Change(Sender: TObject);
    var
      L: TList;
      I,J: Integer;
      T: TTest;
      EI: ITestEvents;
    begin
      try
        L := ClientList.LockList;
        for I :=0 to L.Count-1 do
        begin
          T := TTest(L[I]);
          for J := 0 to T.ConnectionPoint.SinkList.Count - 1 do
          begin
            EI := IUnknown(T.ConnectionPoint.SinkList[J]) as ITestEvents;
            if Assigned(EI) then EI.OnTextChange;
          end;
        end;
      finally
        ClientList.UnlockList;
      end;
    end;
    

       
    Класс TConnectionPoint в свойстве SinkList содержит ссылки на все клиентские приложения, обратившиеся за иотификациоииым интерфейсом.
    Опять-таки, здесь присутствует некоторый "обман" Delphi. По спецификации СОМ для получения ссылок на все клиентские
    приложения надо обращаться к методу Next интерфейса IEnumConnections. Delphi делает это
    самостоятельно, и программист пользуется результатами вызова метода Next, хранящимися в свойстве SinkList.

   
В последнее время довольно много внимания уделяется многозвенным приложениям для работы с базами данных, использующим
технологию DataSnap. Центральное звено в этой архитектуре называется сервером приложений
(Application Server), или сервером доступа к данным (Data Access Server), и этот сервер
поддерживает протокол автоматизации для связи с клиентами. При создании в Delphi удаленного модуля
данных (объекта автоматизации сервера приложений) в окне мастера, которое при этом появляется, флажок
Generate Event support code отсутствует. Причина в том, что для связи с удаленным сервером может использоваться
несколько различных технологий - DCOM, протоколы TCP/IP и HTTP. Уведомление же от
удаленного сервера без написания дополнительного и довольно объемного кода можно получить лишь при помощи технологии DCOM.

   
Со следующего шага мы начнем рассматривать создание контроллеров для приложений Microsoft Office.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий