Добавить в цитаты Настройки чтения

Страница 205 из 372

В асинхронных компонентах можно использовать основанную на ролях систему контроля доступа к его функциональности. Однако, не поддерживается имперсонализация. Аутентификация уже обсуждалась ранее.

Модель событий

Необходимость использования механизма событий часто возникает при разработке распределенных приложений. Классический пример — отслеживание курса акций определенного предприятия. Один компонент (издатель), имеющий доступ к информации с биржи, публикует эту информацию, а другой компонент (подписчик), представляющий интересы некоторого пользователя, получает уведомление о событии, состоящем в том, что курс акций некоторого конкретного предприятия превысил заданный порог.

Рассмотрим прежде всего две ранее использовавшиеся модели событий, недостатки которых устранены в более совершенной модели событий СОМ+:

• Регулярный опрос издателя

Издатель имеет интерфейс, через который подписчик может обратиться к издателю с вопросом — произошло ли заданное событие (курс акций некоторого предприятия превысил некоторый порог). Вопрос реализуется путем вызова некоторого метода, входные параметры которого описывают само событие, а выходные представляют ответ издателя.

Данная модель имеет следующие основные недостатки:

♦ Огромная доля запросов подписчиков к издателю завершается отрицательным ответом (ожидаемое событие еще не произошло), и ресурсы и подписчика и издателя тратятся впустую,

♦ От момента реального возникновения события до того момента, как об этом событии узнает подписчик, проходит определенное время (в среднем — половина длины временного интервала между двумя последовательными опросами издателя данным подписчиком).

• Тесно-связанные события

В рамках этой модели издатель выставляет интерфейс, используя который подписчик подписывается на получение уведомлений об интересующем его событии, передавая издателю указатель на собственный интерфейс (реализованный подписчиком, но описанный издателем), через который издатель и будет уведомлять подписчика о появлении данного события.

Модель тесно связанных событий устраняет упомянутые недостатки предыдущей модели, но не все. Остаются следующие вопросы:

♦ Реализация

Организация подписки, рассылка уведомлений большому числу подписчиков, контроль ошибок и т. п. — сложная задача, которую следует решать не разработчику приложения. Он должен сконцентрироваться на бизнес-логике, а не на построении инфраструктуры, общей для многих приложений. В рамках СОМ была выполнена стандартизация данной модели — описаны интерфейс ICo

♦ Фильтрация уведомлений

Подписчик получает все предназначенные ему уведомления и не может отказаться от получения некоторых из них, не отказываясь от подписки полностью,

♦ Активация подписчика

Издатель получает только указатель на интерфейс подписчика, но не знает его CLSID. Это означает, что подписчик все время должен находиться в активном состоянии. Издатель не сможет создать подписчика при появлении интересующего данного подписчика события.

В СОМ+ предлагается новая модель свободно-связанных событий. Идея состоит в разделении издателя и подписчика посредником, хранящим описание события и подписку на это событие. В роли посредника выступает подсистема событий (сервис операционной системы), все данные о событиях и подписках на них хранятся в СОМ+ каталоге. Подписчик подписывается на интересующие его события независимо от издателя. Издатель, при возникновении некоторого события, по умолчанию инициирует рассылку уведомлений всем подписчикам (собственно рассылка выполняется подсистемой событий). Однако он имеет возможность просмотреть подписку на данное событие и инициировать отправку уведомлений только тем подписчикам, которым пожелает. В свою очередь, подписчик может установить фильтр, ограничивающий приходящие к нему уведомления.





Основными компонентами архитектуры слабо связанных событий являются издатель, подписчик, подсистема событий, событийный интерфейс, событийный класс, экземпляр событийного класса, подписка, фильтры издателя и подписчика. Рассмотрим перечисленные компоненты и сценарии их формирования и использования подробнее.

Событийный класс

В данной модели, как и в модели тесно связанных событий, определяется интерфейс (событийный интерфейс), который должен реализовать каждый подписчик на события, представленные данным интерфейсом. Каждый метод этого интерфейса соответствует некоторому событию, входные [in] параметры метода конкретизируют событие, выходных параметров быть не должно. Уведомление подписчика о некотором событии достигается вызовом соответствующего метода событийного интерфейса, реализованного данным подписчиком.

Однако, если в модели тесно-связанных событий при возникновении некоторого события издатель самостоятельно вызывает соответствующий метод для каждого подписчика, то в данной модели все эти вызовы выполняются автоматически подсистемой событий. Точнее, издатель направляет вызов подсистеме событий, которая транслирует его всем подписчикам.

Событийный класс является основным элементом в данном механизме. Он представляет в подсистеме событий событийный интерфейс, который должны реализовать подписчики.

Рассмотрим все этапы описания и использования событийного класса:

• Разработка событийного класса

Разработчик событийного класса прежде всего разрабатывает событийный интерфейс, методы которого будут вызываться издателем, инициирующем распространение уведомлений о наступлении некоторых событий. Реализовывать этот интерфейс не нужно, т. к. при активации экземпляра событийного класса издателем подсистема событий сама обеспечит его реализацию. Как уже говорилось, параметры всех методов событийного интерфейса должны быть только входными. Разработчик событийного класса должен создать саморегистрирующийся СОМ сервер типа сервер в процессе клиента (DLL), который в процессе своей саморегистрации должен зарегистрировать в реестре машины библиотеку типов, описывающую событийный класс, событийный интерфейс и все его методы.

• Регистрация событийного класса в подсистеме событий

Прежде всего отметим, что в СОМ+ не реализована распределенность базы данных подсистемы событий. Это означает, что после выбора машины, на которой в ее подсистеме событий будет зарегистрирован событийный класс, издатель соответствующего события должен активировать экземпляр событийного класса именно на этой машине. В подсистеме событий именно этой машины должны регистрироваться и подписчики на события, представленные данным событийным классом.

При регистрации событийного класса можно использовать и

Component Services и стандартные интерфейсы для работы с подсистемой событий. Рассмотрим вначале использование стандартных интерфейсов для работы с подсистемой событий:

♦ Прежде всего формируется экземпляр реализованного в системе класса с идентификатором CLSID_CEventClass и запрашивается указатель на интерфейс IEventClass этого класса.

♦ Интерфейс IEventClass используется для задания свойств класса CLSID_CEventClass, которые должны определить регистрируемый событийный класс:

— CLSID регистрируемого событийного класса задается вызовом метода IEventClass:: put_EventClassID (), где параметром является BSTR строка, задающая CLSID событийного класса.

— ProgID регистрируемого событийного класса задается вызовом метода IEventClass:: put_EventClassName (), где параметром является BSTR строка, задающая ProgID событийного класса.

— IID событийного интерфейса регистрируемого событийного класса задается вызовом метода IEventClass::put_FiringInterfaceID (), где параметром является BSTR строка, задающая IID событийного интерфейса.