最近デスクトップにあるアプリ同士で通信を行うために linux でよく使われるようになった dbus というのを試してみた。ファイルやソケットを使って他のアプリと通信すると、データをいちいち文字列に変換しないといけないのだが、dbus を使うと、単にメソッド呼び出しをする感じで通信が出来て楽なのだそうだ。とりあえず python で動かしてみる。
#!/usr/bin/env python "Ask what messages dbus can answer." import dbus # セッションバス(ユーザごとのバス)と接続する。 bus = dbus.SessionBus() # bus name が org.freedesktop.DBus で # object path が /org/freedestop/DBus に接続 object = bus.get_object("org.freedesktop.DBus", "/org/freedestop/DBus") # オブジェクトの中身を尋ねる print object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable") # 見つけた ListNames を問い合わせる。 print object.ListNames(dbus_interface="org.freedesktop.DBus")
他のアプリのオブジェクトを指定するには、bus name と object path というのを使う。このふたつでオブジェクトを特定して、メッセージを送ると答えが帰る。メッセージを送るには、引数の他に、インタフェースという物が必要だ。あるメッセージは特定のインタフェースに属するという事になっている。
まとめると、あるメッセージを送るには次のように階層的に指定してゆく
- アドレス(環境変数 DBUS_SESSION_BUS_ADDRESS で指定)
- bus_name (例 org.freedesktop.DBus)
- object path (例 /org/freedestop/DBus) (これは ListName で取れないのでどうやって探すのか謎)
- インタフェース (例 org.freedesktop.DBus.Introspectable)
- メソッド名 (例 Introspect)
上の例では、まず Introspect() でどんなメソッドがあるのか調べてから、使いかたの簡単そうな、ListNames() を送っている。
もうちょっとましな面白い例として、画面におしらせを表示します。
#!/usr/bin/env python "Show notifier" import dbus bus = dbus.SessionBus() object = bus.get_object("org.freedesktop.Notifications", "/org/freedesktop/Notifications") print object.Introspect(dbus_interface="org.freedesktop.DBus.Introspectable") object.Notify('dbus test', 0, '', 'Hi there','hello!', [], {}, -1, dbus_interface="org.freedesktop.Notifications")