KasperskyOS Community Edition 1.1

Компонент MessageBus

Компонент MessageBus реализует шину сообщений, которая обеспечивает прием, распределение и доставку сообщений между приложениями, работающими под KasperskyOS. Шина построена по принципу издатель-подписчик. Использование шины сообщений позволяет избежать создания большого количества IPC-каналов для связывания каждого приложения-подписчика с каждым приложением-издателем.

Сообщения, передаваемые через шину MessageBus, не могут содержать данные. Эти сообщения могут использоваться только для уведомления подписчиков о событиях. См. "Структура сообщения" ниже.

Компонент MessageBus представляет собой дополнительный уровень абстракции над KasperskyOS IPC, который позволяет упростить процесс разработки и развития приложений прикладного уровня. MessageBus является отдельной программой доступ к которой осуществляется через IPC, но при этом разработчикам предоставляется библиотека доступа к MessageBus, которая позволяет избежать использования IPC-вызовов напрямую.

API библиотеки доступа предоставляет следующие интерфейсы:

  • IProviderFactory – предоставляет фабричные методы для получения доступа к экземплярам остальных интерфейсов;
  • IProviderControl – интерфейс для регистрации и дерегистрации издателя и подписчика в шине;
  • IProvider (компонент MessageBus) – интерфейс для передачи сообщения в шину;
  • ISubscriber – интерфейс обратного вызова для передачи сообщения подписчику;
  • IWaiter – интерфейс ожидания обратного вызова при появлении соответствующего сообщения.

Структура сообщения

Каждое сообщение содержит два параметра:

  • topic – идентификатор темы сообщения;
  • id – дополнительный параметр, специфицирующий сообщение.

Параметры topic и id уникальны для каждого сообщения. Интерпретация topic+id определяется контрактом между издателем и подписчиком. Например, если изменяются конфигурационные данные с которыми работают издатель и подписчик, издатель высылает сообщение об изменении данных и id конкретной записи с новыми данными. Подписчик, пользуясь отличными от MessageBus механизмами, получает новые данные по ключу id.

В этом разделе

Интерфейс IProviderFactory

Интерфейс IProviderControl

Интерфейс IProvider (компонент MessageBus)

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner

В начало
[Topic messagebus_component]

Интерфейс IProviderFactory

Интерфейс IProviderFactory предоставляет фабричные методы для получения интерфейсов, необходимых для работы с компонентом MessageBus.

Описание интерфейса IProviderFactory представлено в файле messagebus/i_messagebus_control.h.

Для получения экземпляра интерфейса IProviderFactory используется свободная функция InitConnection(), которая принимает имя IPC-соединения прикладной программы с программой MessageBus. Имя соединения задается в файле init.yaml.in при описании конфигурации решения. В случае успешного подключения выходной параметр содержит указатель на интерфейс IProviderFactory.

  • Для получения интерфейса регистрации и дерегистрации (см. "Интерфейс IProviderControl") издателей и подписчиков в шине сообщений используется метод IProviderFactory::CreateBusControl().
  • Для получения интерфейса, содержащего методы для отправки издателем сообщений в шину (см. "Интерфейс IProvider (компонент MessageBus)"), используется метод IProviderFactory::CreateBus().
  • Для получения интерфейсов, содержащих методы для получения подписчиком сообщений из шины (см. "Интерфейсы ISubscriber, IWaiter и ISubscriberRunner") используются методы IProviderFactory::CreateCallbackWaiter и IProviderFactory::CreateSubscriberRunner().

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

i_messagebus_control.h (фрагмент)

class IProviderFactory

{

...

virtual fdn::ResultCode CreateBusControl(IProviderControlPtr& controlPtr) = 0;

virtual fdn::ResultCode CreateBus(IProviderPtr& busPtr) = 0;

virtual fdn::ResultCode CreateCallbackWaiter(IWaiterPtr& waiterPtr) = 0;

virtual fdn::ResultCode CreateSubscriberRunner(ISubscriberRunnerPtr& runnerPtr) = 0;

...

};

...

fdn::ResultCode InitConnection(const std::string& connectionId, IProviderFactoryPtr& busFactoryPtr);

В начало
[Topic messagebus_component_iproviderfactory]

Интерфейс IProviderControl

Интерфейс IProviderControl предоставляет методы для регистрации и дерегистрации издателей и подписчиков в шине сообщений.

Описание интерфейса IProviderControl представлено в файле messagebus/i_messagebus_control.h.

Для получение экземпляра интерфейса используется интерфейс IProviderFactory.

Регистрация и дерегистрация издателя

Для регистрации издателя в шине сообщений используется метод IProviderControl::RegisterPublisher(). Метод принимает тему сообщения и помещает в выходной параметр уникальный идентификатор клиента шины. Если тема уже зарегистрирована в шине, то вызов будет отклонен и идентификатор клиента не будет заполнен.

Для дерегистрации издателя в шине сообщений используется метод IProviderControl::UnregisterPublisher(). Метод принимает идентификатор клиента шины, полученный при регистрации. Если указан идентификатор не зарегистрированный как идентификатор издателя, то вызов будет отклонен.

i_messagebus_control.h (фрагмент)

class IProviderControl

{

...

virtual fdn::ResultCode RegisterPublisher(const Topic& topic, ClientId& id) = 0;

virtual fdn::ResultCode UnregisterPublisher(ClientId id) = 0;

...

};

Регистрация и дерегистрация подписчика

Для регистрации подписчика в шине сообщений используется метод IProviderControl::RegisterSubscriber(). Метод принимает имя подписчика и список тем, на которые нужно подписаться, а в выходной параметр помещает уникальный идентификатор клиента шины.

Для дерегистрации подписчика в шине сообщений используется метод IProviderControl::UnregisterSubscriber(). Метод принимает идентификатор клиента шины, полученный при регистрации. Если указан идентификатор не зарегистрированный как идентификатор подписчика, то вызов будет отклонен.

i_messagebus_control.h (фрагмент)

class IProviderControl

{

...

virtual fdn::ResultCode RegisterSubscriber(const std::string& subscriberName, const std::set<Topic>& topics, ClientId& id) = 0;

virtual fdn::ResultCode UnregisterSubscriber(ClientId id) = 0;

...

};

В начало
[Topic messagebus_component_icontrol]

Интерфейс IProvider (компонент MessageBus)

Интерфейс IProvider предоставляет методы для отправки издателем сообщений в шину.

Описание интерфейса IProvider представлено в файле messagebus/i_messagebus.h.

Для получение экземпляра интерфейса используется интерфейс IProviderFactory.

Отправка сообщения в шину

Для оправки сообщения в шину используется метод IProvider::Push(). Метод принимает идентификатор клиента шины, полученный при регистрации, и идентификатор сообщения. Если очередь сообщений в шине заполнена, то вызов будет отклонен.

i_messagebus.h (фрагмент)

class IProvider

{

public:

...

virtual fdn::ResultCode Push(ClientId id, BundleId dataId) = 0;

...

};

В начало
[Topic messagebus_component_iprovider]

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner

Интерфейсы ISubscriber, IWaiter и ISubscriberRunner предоставляют методы для получения и обработки подписчиком сообщений из шины.

Описания интерфейсов ISubscriber, IWaiter и ISubscriberRunner представлено в файле messagebus/i_subscriber.h.

Для получение экземпляров интерфейсов IWaiter и ISubscriberRunner используется интерфейс IProviderFactory. Реализация callback-интерфейса ISubscriber предоставляется приложением-подписчиком.

Получение сообщения из шины

Чтобы перевести подписчика в режим ожидания сообщения от шины, вы можете использовать метод IWaiter::Wait() или ISubscriberRunner::Run(). Методы принимают идентификатор клиента шины и указатель на callback-интерфейс ISubscriber. Если идентификатор клиента не зарегистрирован, то вызов будет отклонен.

Мы не рекомендуем использовать интерфейс IWaiter, поскольку вызов метода IWaiter::Wait() является блокирующим.

При получении сообщения из шины будет вызван метод ISubscriber::OnMessage(). Метод принимает тему и идентификатор сообщения.

i_subscriber.h (фрагмент)

class ISubscriber

{

...

virtual fdn::ResultCode OnMessage(const std::string& topic, BundleId id) = 0;

};

...

class IWaiter

{

...

[[deprecated("Use ISubscriberRunner::Run method instead.")]]

virtual fdn::ResultCode Wait(ClientId id, const ISubscriberPtr& subscriberPtr) = 0;

};

...

class ISubscriberRunner

{

...

virtual fdn::ResultCode Run(ClientId id, const ISubscriberPtr& subscriberPtr) = 0;

};

В начало
[Topic messagebus_component_isubwait]