I have a situation where I have a single ObServer object and a set of Clients. ObServer and clients connected through D-BUS (IPC). ObServer has generic interface for all clients. But, time to time ObServer needs to notify clients about some events. Clients listen for a ObServer Generic interface signal OnNotify().
Question: How to emit D-BUS signal (OnNotify()) from ObServer to specified client (instead of broadcast to all) ?
p.s
Qt D-BUS used for wrapping but any approach are welcome.
You can't. Signals are received by all clients that have registered for that signal on a DBus interface.
You can either add a parameter to the OnNotify
signal, and handle it in the client, or create separate signals for each client. However, if you want this component to be dynamic (add clients at runtime), you have to go with the first approach (parameter to OnNotify
).
EDIT: more information on signals
A signal is defined as follows:
A signal in DBus consists of a single message, sent by one process to any number of other processes. That is, a signal is a unidirectional broadcast. The signal may contain arguments (a data payload), but because it is a broadcast, it never has a "return value." Contrast this with a method call (see the section called “Calling a Method - Behind the Scenes”) where the method call message has a matching method reply message.
The emitter (aka sender) of a signal has no knowledge of the signal recipients. Recipients register with the bus daemon to receive signals based on "match rules" - these rules would typically include the sender and the signal name. The bus daemon sends each signal only to recipients who have expressed interest in that signal.
EDIT: updated answer in light of Dmitry's comments.
Filtering dbus signals will not work with any of the current available bindings (didn't check all of them, only 2 (dbus-cpp and qt), so anyone can follow up on this).
However it is possible to set the DESTINATION
field in the header of the dbus message, using a function that is available in the dbus interface (dbus-message.h
):
dbus_bool_t dbus_message_set_destination (DBusMessage *message, const char *destination)
In case of QT bindings, you have to modify the bindings as follows: in qdbusmessage.cpp
in the method
DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDBusError *error)
on the case branch DBUS_MESSAGE_TYPE_SIGNAL
you need to make a call to q_dbus_message_set_destination
.
Also the destination must be available from the upper layers. Easiest way would be to extend the QDBusMessage
class in order to retain the destination, and then pass it below to the dbus layer.
If you are able to modify the QT bindings in your project, then you might do such a maneuver :).
来源:https://stackoverflow.com/questions/11019048/selective-d-bus-signal-emitting-from-observer-unicast-signal