3月
14
2010
分類:
最近更新:
2010-03-14
Write a D-Bus service by Ruby
Install Ruby DBus
前往 ruby-dbus ,下載壓縮包 (tarball) 並解壓。
詳細安裝方式請閱讀壓縮包內的 README ,基本上只需要執行下列三個動作:
- ruby setup.rb config
- ruby setup.rb setup
- sudo ruby setup.rb install
Test:
irb> require 'dbus'
true
Write a D-Bus service
#!/usr/bin/ruby
# coding: utf-8
=begin rdoc
= Ruby DBus example
Ruby D-Bus Tutorial:
http://trac.luon.net/data/ruby-dbus/tutorial/index.html
Ruby D-Bus implementation:
https://trac.luon.net/ruby-dbus/
查詢 Hello service:
dbus-send --session --print-reply \
--dest=blog.rock.hello \
/blog/rock/hello \
org.freedesktop.DBus.Introspectable.Introspect
調用 say method:
dbus-send --session --print-reply --dest=blog.rock.hello \
/blog/rock/hello \
blog.rock.hello.say \
string:"Hello" boolean:true
調用 stop method:
dbus-send --session --print-reply --dest=blog.rock.hello \
/blog/rock/hello \
blog.rock.hello.stop
觸發 event_say signal:
dbus-send --session --print-reply --dest=blog.rock.hello \
--type=signal /blog/rock/hello \
blog.rock.hello.event_say \
string:"Signal hello"
=end
require 'dbus'
=begin rdoc
Hello service
Inheriting from DBus::Object
DBus Service name: blog.rock.hello
=end
class Hello < DBus::Object
@@name = 'blog.rock.hello'
@@path = '/' + @@name.tr('.', '/')
# Service name
def self.name
@@name
end
# Service object path
def self.path
@@path
end
# Export interface, *blog.rock.hello*, in this service.
# One DBus service could have many interfaces.
dbus_interface 'blog.rock.hello' do
# Export *say* method in this interface.
# say(message, timeout)
#
# in: input arguments
# out: output
# s: type string
# b: type boolean
# http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures
dbus_method :say, "in message:s, in timeout:b, out reply:s" do |message, timeout|
puts "[INFO] message: #{message}, timeout: #{timeout}"
notify 'Say', message, timeout
return "I say #{message}"
end
# Export *stop* method in this interface.
# stop()
dbus_method :stop do
main_quit
end
# Export *event_say* signal in this interface.
# yield message
#
# Signal only accepts input arguments.
dbus_signal :event_say, "message:s"
end
attr_reader :bus
def initialize
# @bus = DBus::SessionBus.instance
# or
@bus = DBus.session_bus
super(@@path)
service = bus.request_service(@@name)
service.export(self)
init_notifier
end
private
def init_notifier #:nodoc:
notifications_service = 'org.freedesktop.Notifications'
notifications_object = '/' + notifications_service.tr('.', '/')
notifications_interface = notifications_service
@notifier = bus.service(notifications_service).object(notifications_object)
# This is a proxy object.
# We need to do this before invoke any dbus method.
# This fills in instance.
@notifier.introspect
# Set default interface.
@notifier.default_iface = notifications_interface
end
def notify(title='', message='', timeout=false, icon='icon') #:nodoc:
@notifier.Notify('Hello', 0, icon, title, message, [], {}, timeout ? 1 : 0)
end
end
=begin rdoc
Signal Recipient
Listen to *event_say* of blog.rock.hello.
=end
class SignalRecipient
def initialize
bus = DBus.session_bus
hello_service = Hello.name
hello_path = Hello.path
hello_interface = Hello.name
hello_object = bus.service(hello_service).object(hello_path)
# This is a proxy object.
# We need to do this before invoke any method.
# This fills in instance.
hello_object.introspect
# Waiting for a signal
# 指定介面與訊號名稱
# event_say pass a string:message.
hello_interface_object = hello_object[hello_interface]
hello_interface_object.on_signal(bus, 'event_say') do |message|
puts "I get signal(#{message})"
end
end
end
def main_quit
$main.quit
end
service = Hello.new
recipient = SignalRecipient.new
puts "Working..."
$main = DBus::Main.new
$main << service.bus
$main.run
D-Bus signal
有 2 種方式綁定 D-Bus signal。
第一種方式: bind with interface。interface.on_signal(bus, signal_name, &block)
hello_interface_object = hello_object[hello_interface]
hello_interface_object.on_signal(bus, 'event_say') do |message|
puts "I get signal(#{message})"
end
第二種方式: bind with proxy object。object.on_signal(signal_name, &block)
# You must set default_iface before bind the signal.
hello_object.default_iface = hello_interface
hello_object.on_signal('event_say') do |message|
puts "I get signal(#{message})"
end
相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/11949071.html