class DBus::BusConnection
A regular Bus {Connection}. As opposed to a peer connection to a single counterparty with no daemon in between.
Constants
- RELEASE_NAME_REPLY_NON_EXISTENT
The given name does not exist on this bus.
- RELEASE_NAME_REPLY_NOT_OWNER
The caller was not the primary owner of this name, and was also not waiting in the queue to own this name.
- RELEASE_NAME_REPLY_RELEASED
The caller has released his claim on the given name. Either the caller was the primary owner of the name, and the name is now unused
or taken by somebody waiting in the queue for the name,
or the caller was waiting in the queue for the name and has now been removed from the queue.
Attributes
The unique name (by specification) of the message.
Public Class Methods
Connect, authenticate, and send Hello. @param addresses [String] @see dbus.freedesktop.org/doc/dbus-specification.html#addresses
# File lib/dbus/bus.rb, line 31 def initialize(addresses) super @unique_name = nil @proxy = nil send_hello end
Public Instance Methods
Asks bus to send us messages matching mr, and execute slot when received @param match_rule [MatchRule,#to_s] @return [void]
# File lib/dbus/bus.rb, line 163 def add_match(match_rule, &slot) mrs = match_rule.to_s rule_existed = super(mrs, &slot) # don't ask for the same match if we override it return if rule_existed DBus.logger.debug "Asked for a new match" proxy.AddMatch(mrs) end
# File lib/dbus/bus.rb, line 151 def on_name_acquired(&handler) proxy.on_signal("NameAcquired", &handler) end
# File lib/dbus/bus.rb, line 155 def on_name_lost(&handler) proxy.on_signal("NameLost", &handler) end
Set up a ProxyObject
for the bus itself, since the bus is introspectable. @return [ProxyObject] that always returns an array
({DBus::ApiOptions#proxy_method_returns_array})
Returns the object.
# File lib/dbus/bus.rb, line 42 def proxy if @proxy.nil? xml_filename = File.expand_path("org.freedesktop.DBus.xml", __dir__) xml = File.read(xml_filename) path = "/org/freedesktop/DBus" dest = "org.freedesktop.DBus" pof = DBus::ProxyObjectFactory.new( xml, self, dest, path, api: ApiOptions::A0 ) @proxy = pof.build["org.freedesktop.DBus"] end @proxy end
@param name [BusName] the name to release
# File lib/dbus/bus.rb, line 146 def release_name(name) name = BusName.new(name) proxy.ReleaseName(name).first end
@param match_rule [MatchRule,#to_s] @return [void]
# File lib/dbus/bus.rb, line 175 def remove_match(match_rule) mrs = match_rule.to_s rule_existed = super(mrs) # don't remove nonexisting matches. return if rule_existed # FIXME: if we do try, the Error.MatchRuleNotFound is *not* raised # and instead is reported as "no return code for nil" proxy.RemoveMatch(mrs) end
Request a well-known name so that clients can find us. @note Parameters other than name are advanced, you probably don’t need them.
With no boolean flags, running a second instance of a program that calls ‘request_name` will result in the second one failing, which this library translates to an exception. If you want the second instance to take over, you need both `allow_replacement: true` and `replace_existing: true.`
@param name [BusName] the requested name @param replace_existing [Boolean]
Replace an existing owner of the name, if that owner set *allow_replacement*.
@param allow_replacement [Boolean]
Other connections that specify *replace_existing* will be able to take the name from us. We will get {#on_name_lost NameLost}. If we specified *queue* we may get the name again, with {#on_name_acquired NameAcquired}.
@param queue [Boolean]
Affects the behavior when the bus denies the name (sooner or later). - If `false` (default), it is recommended to let the `NameRequestError` fall through and end your program. - If `true`, you should `rescue` the `NameRequestError` and set up {#on_name_acquired NameAcquired} and {#on_name_lost NameLost} handlers. Meanwhile, the bus will put us in a queue waiting for *name* (this is the "sooner" case). Also, if we had `allow_replacement: true`, another connection can cause us to lose the name. We will be moved back to the queue, waiting for when the other owners give up (the "later" case).
@param flags [Integer,nil]
If specified, overrides the boolean parameters. Use a bitwise sum `|` of: - NAME_FLAG_ALLOW_REPLACEMENT - NAME_FLAG_REPLACE_EXISTING - NAME_FLAG_DO_NOT_QUEUE Note that `0` implies `queue: true`.
@return [REQUEST_NAME_REPLY_PRIMARY_OWNER,REQUEST_NAME_REPLY_ALREADY_OWNER] on success @raise [NameRequestError] with error_code REQUEST_NAME_REPLY_EXISTS or REQUEST_NAME_REPLY_IN_QUEUE, on failure @raise DBus::Error
another way to fail is being prohibited to own the name
which is the default on the system bus
@see dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-request-name
@example Simple usage
bus = DBus.session_bus bus.object_server.export(DBus::Object.new("/org/example/Test")) bus.request_name("org.example.Test") # main loop
@example Second instance taking over
bus = DBus.session_bus bus.object_server.export(DBus::Object.new("/org/example/Test")) bus.on_name_lost { exit } bus.request_name("org.example.Test", allow_replacement: true, replace_existing: true) # main loop
@example Second instance waiting for its turn
bus = DBus.session_bus bus.object_server.export(DBus::Object.new("/org/example/Test")) bus.on_name_acquired { @owner = true } begin bus.request_name("org.example.Test", queue: true) rescue DBus::Connection::NameRequestError => e @owner = false end # main loop
# File lib/dbus/bus.rb, line 120 def request_name(name, allow_replacement: false, replace_existing: false, queue: false, flags: nil) if flags.nil? flags = (allow_replacement ? NAME_FLAG_ALLOW_REPLACEMENT : 0) | (replace_existing ? NAME_FLAG_REPLACE_EXISTING : 0) | (queue ? 0 : NAME_FLAG_DO_NOT_QUEUE) end name = BusName.new(name) r = proxy.RequestName(name, flags).first handle_return_of_request_name(r, name) end
Makes a {ProxyService} with the given name. Note that this succeeds even if the name does not exist and cannot be activated. It will only fail when calling a method. @return [ProxyService]
# File lib/dbus/bus.rb, line 190 def service(name) # The service might not exist at this time so we cannot really check # anything ProxyService.new(name, self) end
Private Instance Methods
Send a hello messages to the bus to let it know we are here.
# File lib/dbus/bus.rb, line 201 def send_hello m = Message.new(DBus::Message::METHOD_CALL) m.path = "/org/freedesktop/DBus" m.destination = "org.freedesktop.DBus" m.interface = "org.freedesktop.DBus" m.member = "Hello" send_sync(m) do |rmsg| @unique_name = rmsg.destination DBus.logger.debug "Got hello reply. Our unique_name is #{@unique_name}" end end