- •Розподілені системи обробки інформації
- •Передмова
- •Розділ 1. Огляд компонентних технологій створення розподілених програмних систем
- •1.1. Узагальнена архітектура і механізм функціонування об'єктних розподілених систем
- •1.2. Основні приклади технологій створення розподілених систем
- •1.3. Переваги використання розподілених технологій
- •Розділ 2. Розроблення розподілених систем на основі модели com/dcom у Delphi
- •2.1. Використання dll у Delphi
- •2.1.1. Поняття dll
- •2.1.2. Створення dll у середовищі Delphi (експорт)
- •2.1.3. Використання dll у Delphi (імпорт)
- •2.1.4. Створення динамічних бібліотек для редагування ресурсів
- •2.2. Основи сом-технології
- •2.2.1. Загальний опис
- •2.2.2. Базові поняття
- •2.2.3. Бібліотека сом
- •2.2.4. Бібліотека типів
- •2.3.2. Сервер сом у Delphi
- •2.3.3. Бібліотека типів у delphі
- •2.4. Створення системи клієнт-сервер на основі базового com-об’єкту у складі внутрішнього сервера
- •2.4.1. Створення сом-сервера
- •2.4.2. Створення сом-клієнта
- •2.4.3. Використання сом-об’єкту в клієнтській програмі
- •2.5. Механізм міжпроцесного обміну
- •2.6. Створення систем клієнт-сервер на основі зовнішнього базового сом-об’єкту
- •2.6.1. Основні поняття
- •2.6.2. Засоби організації потокової взаємодії клієнта і сервера
- •2.6.3. Методи формування екземпляра сом-об’єкту
- •2.6.4. Формування екземпляра зовнішнього сом-об’єкту
- •2.6.5. Створення сом-сервера
- •2.6.6. Створення сом-клієнта
- •2.7. Автоматизація
- •Створення сервера автоматизації;
- •2.7.1. Базові поняття
- •2.7.2. Сервер автоматизації
- •2.7.3. Контролер автоматизації
- •2.8. Створення системи клієнт-сервер на основі внутрішнього сервера автоматизації
- •2.8.1. Об'єкт автоматизації. Клас tAutoObject
- •2.8.2. Вбудований сервер автоматизації
- •2.8.3. Створення клієнта автоматизації
- •2.9. Зовнішній сервер автоматизації
- •2.9.1. Основні визначення
- •2.9.2. Виконання маршалінгу з рядками, шрифтами і зображеннями
- •2.9.3. Перетворення наявного застосунка в сом-сервер автоматизації
- •2.9.4. Створення клієнта автоматизації
- •2.10. Події в сом і зворотні виклики на основі інтерфейсів диспетчирування
- •2.10.1. Створення сервера автоматизації
- •3. Формування бібліотеки типів
- •4. Формування методів
- •5. Реєстрація сервера
- •2.10.2. Створення клієнтського застосунка
- •2.10.3. Підключення множини клієнтів до сервера
- •2.11. Інтерфейси зі зворотним викликом
- •2.11.1. Створення сервера
- •2.11.2. Створення клієнтського застосунка
- •2.12. Технологія ActiveХ
- •2.12.1. Використання готових елементів АctiveХ
- •2.12.2. Розроблення власних елементів АctiveХ
- •2.12.3. Поширення елементів керування ActiveХ і форм ActiveХForm у Web-середовище
- •2.14. Dcom технологія
- •2.14.1. Загальна схема взаємодії сом-клієнта і сом-сервера
- •2.14.2. Розроблення системи «клієнт-віддалений сом-сервер»
- •Розділ 3. Проектування розподілених систем на платформі Microsoft .Net
- •3.1.1. Здійсненя викликань з типів .Net до типів сом
- •3.1.2. Звернення клієнта сом до збірки .Net
- •3.2. Об’єктно-орієнтована архітектура .Net Remotіng – основа створення розподілених систем Mіcrosoft .Net.
- •3.2.1. Створення системи клієнт-сервер на основі технології Remoting
- •Розділ 4. Створення системи "клієнт - сервер" на основі технології corba
- •4.1. Загальні теоретичні відомості
- •4.2. Створення серверного застосунка
- •1. Створення файла опису інтерфейсу
- •Викликання конструктора створення corba сервера
- •Формуємо модуль Unit1
- •Формуємо реалізацію методу
- •4.3. Створення клієнтського застосунка
- •Викликання конструктора corba-клієнта
- •2. Формування форми
- •3. Запуск застосунка
- •Приклад програмних кодів сервера
- •4.4. Порівняльний аналіз технологій сом і соrва
- •4.4.1. Основні принципи об'єктних моделей
- •4.4.2. Об'єктні моделі
- •4.4.3. Підтримка операційних систем
- •4.4.4. Формальний опис архітектури і проблеми реалізації
- •4.4.5. Підсумки порівняння
- •Літературні джерела
2.10.3. Підключення множини клієнтів до сервера
У програмному коді сервера, що існує зараз, є недолік. Незважаючи на те, що для обслуговування множини клієнтів можна запустити єдиний екземпляр застосунка-сервера, цей сервер зможе згенерувати події тільки для першого підключеного клієнта. А цього не досить.
Щоб усунути цей недолік, доведеться внести корективи як у програмний код сервера, так і у програмний код застосунка-клієнта.
Спочатку, необхідно змінити метод Initialize, який повинен мати такий вигляд:
procedure TEventIntf.Initialize;
begin
inherited Initialize;
FConnectionPoints := TConnectionPoints.Create(Self);
if AutoFactory.EventTypeInfo <> nil then FConnectionPoints. CreateConnectionPoint(AutoFactory.EventIID, ckMulti, EventConnect);
end;
Зверніть увагу на те, що змінено передостанній параметр методу CreateConnectionPoint. Замість значення ckSingle тепер використовується ckMulti. Це забезпечить серверу можливість пам’ятати про всіх клієнтів, які підключені до нього у цей момент.
Так, коли сервер може відстежувати багато паралельних підключень, необхідно організувати перегляд по черзі всіх активних підключень. Для цього скористаймося лічильником (нумератором), яким володіє інтерфейс IConnectionPointContainer. Для звернення до цього лічильника можна скористатися функцією, що подібна до тої, яка наведена нижче:
function TEventIntf.GetEnumerator: IEnumConnections;
var
Container: IConnectionPointContainer;
ConnectionPoint: IConnectionPoint;
begin
OleCheck(QueryInterface (IConnectionPointContainer, Container));
OleCheck(Container.FindConnectionPointAutoFactory.EventIID, ConnectionPoint));
ConnectionPoint.EnumConnections(Result);
end;
Після того, як дані від лічильника підключень вже отримані, необхідно для кожного підключення збудити подію. Нижче наведено скорегований програмний код процедури обробки події, яка підтримує множину підключень.
procedure TEventIntf.SendText(const Text: WideString);
var
Enum: IEnumConnections;
ConnectData: TConnectData;
Fetched: Cardinal;
begin
Enum := GetEnumerator;
if Enum <> nil then
begin
while Enum.Next(1, ConnectData, @Fetched) = S_OK do
if ConnectData.pUnk <> nil then
(ConnectData.pUnk as IEventIntfEvents).OnText(Text);
end;
end;
Останння зміна, яку необхідно внести у програму сервера, має забезпечити реєстрацію сервера у таблиці виконуваних об’єктів Windows. Для цього у кінець коду методу Initialize необхідно додати рядок:
RegisterActiveObject (self as IUnknown, CLASS_EventIntf, ACTIVEOBJECT_WEAK, FObjectID);
Визначення цієї функції має вигляд:
function RegisterActiveObject(unk: IUnknown; const clsid: TCLSID; dwFlags: Longint; out dwRegister: Longint): HResult; stdcall;
Згідно з визначенням останній параметр (у прикладі, що подано вище, цей параметр має назву FObjectID) має бути глобальною змінною типу Longint. Після виконання функції цей параметр буде містити значення ідентифікатора сервера у таблиці виконуваних об’єктів.
Щоб видалити елемент, що відповідає серверу, з таблиці виконуваних об’єктів Windows, необхідно створити метод Destroy і включити до нього виклик функції RevokeActiveObject:
RevokeActiveObject(FObjectID, nil);
На цьому зміни у програмі сервера, покликані забезпечити нормальну взаємодію з множиною клієнтів, обмежуються.
На стороні клієнта потрібно внести зміни в код методу FormCreate, після чого він повинен виглядати, як наведено нижче:
procedure TForm1.FormCreate(Sender: TObject);
var
Obj: IUnknown;
begin
GetActiveObject(CLASS_EventIntf, nil, Obj);
if Obj <> nil then
//F – це глобальна змінна типу IEventIntf
F := Obj as IEventIntf
else
F := CoEventIntf.Create;
EventIntf1.Connect(F, IEventIntfEvents);
//або EventIntf1.ConnectTo(F, IEventIntfEvents);
end;
Функція GetActiveObject шукає активізований екземпляр сервера автоматизації EventSrv. Якщо такий знайдеться, він і буде надалі використовуватися клієнтом. Якщо ж жодного активного екземпляра сервера знайти не вдасться, метод CoEventIntf.Create створить новий екземпляр.