Селективный сигнал D-BUS, исходящий от ObServer (одноадресный сигнал)
У меня есть ситуация, когда у меня есть один объект ObServer и набор клиентов. ObServer и клиенты подключены через D-BUS (IPC). ObServer имеет универсальный интерфейс для всех клиентов. Но время от времени ObServer должен уведомлять клиентов о некоторых событиях. Клиенты прослушивают общий интерфейс ObServer для сигнала OnNotify().
Вопрос: Как передать сигнал D-BUS (OnNotify()) от ObServer указанному клиенту (вместо широковещательной рассылки всем)?
п.с.
Qt D-BUS используется для упаковки, но любой подход приветствуется.
1 ответ
Ты не можешь Сигналы принимаются всеми клиентами, которые зарегистрировались для этого сигнала на интерфейсе DBus.
Вы можете добавить параметр в OnNotify
сигнал, и обработать его в клиенте, или создать отдельные сигналы для каждого клиента. Однако, если вы хотите, чтобы этот компонент был динамическим (добавьте клиентов во время выполнения), вы должны использовать первый подход (параметр OnNotify
).
РЕДАКТИРОВАТЬ: больше информации о сигналах
Сигнал определяется следующим образом:
Сигнал в DBus состоит из одного сообщения, отправленного одним процессом любому количеству других процессов. То есть сигнал является однонаправленной трансляцией. Сигнал может содержать аргументы (полезные данные), но поскольку он является широковещательным, он никогда не имеет "возвращаемого значения". Сравните это с вызовом метода (см. Раздел "Вызов метода - за кулисами"), где сообщение вызова метода имеет соответствующее ответное сообщение метода.
Излучатель (он же отправитель) сигнала не знает получателей сигнала. Получатели регистрируются в демоне шины для получения сигналов, основанных на "правилах соответствия" - эти правила обычно включают отправителя и имя сигнала. Демон шины отправляет каждый сигнал только получателям, которые проявили интерес к этому сигналу.
РЕДАКТИРОВАТЬ: обновленный ответ в свете комментариев Дмитрия.
Фильтрация сигналов dbus не будет работать ни с одной из текущих доступных привязок (не проверил их все, только 2 (dbus-cpp и qt), так что любой может следить за этим).
Однако можно установить DESTINATION
поле в заголовке сообщения dbus, используя функцию, которая доступна в интерфейсе dbus (dbus-message.h
):
dbus_bool_t dbus_message_set_destination (DBusMessage *message, const char *destination)
В случае привязок QT, вы должны изменить привязки следующим образом: qdbusmessage.cpp
в методе
DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error)
на ветке дела DBUS_MESSAGE_TYPE_SIGNAL
вам нужно позвонить q_dbus_message_set_destination
,
Также пункт назначения должен быть доступен с верхних слоев. Проще всего было бы продлить QDBusMessage
Класс, чтобы сохранить место назначения, а затем передать его ниже на уровень dbus.
Если вы можете изменить привязки QT в своем проекте, то вы можете сделать такой маневр:).