Dbus-monitör çıkışı nasıl okunur?

17

Dbus’un nasıl çalıştığını anlamak için dbus-monitor ile uğraşıyorum. Ubuntu ortamı. Bu konuda birkaç sorum var:

  1. Lütfen aşağıdakileri düzgün okumamı söyler misiniz? Büyük fikri anlıyorum, ama detayları değil.

    signal sender=:1.1948 -> dest=(null destination) serial=1829990 path=/org/ayatana/menu/DA00003; interface=org.ayatana.dbusmenu; member=ItemPropertyUpdated
    int32 23
    string "enabled"
    variant boolean true
    method call sender=:1.6 -> dest=org.freedesktop.Notifications serial=1399 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications;
    member=GetCapabilities
    

    İlkinin bir sinyal olduğunu anladım, ikincisi ise bir yöntem. hedef , bir sinyal için belirli bir alıcı / yuva olabileceği anlamına mı geliyor? Üyelik nedir? Ve sinyalden geçen argümanları izleyen listenin öğeleri nelerdir? Gönderen ve diziler nedir?

  2. Ses denetimi ve bildirimler arasındaki ilişki hakkında bir şey fark ettim. Dbus monitör çıkışından okuduğum kadarı

    method call sender=:1.6 -> dest=org.freedesktop.Notifications serial=1400 path=/org/freedesktop/Notifications; interface=org.freedesktop.Notifications; member=Notify
    string "gnome-settings-daemon"
    uint32 0
    string "notification-audio-volume-medium"
    string " "
    string ""
    array [
    ]
    array [
    dict entry(
    string "value"
    variant int32 38
    )
    dict entry(
    string "x-canonical-private-synchronous"
    variant string "volume"
    )
    ]
    int32 -1
    

    Bildirim, yöntemiyle tetikleniyor gibi görünüyor. Sadece neden bu şekilde çalıştığını anlamıyorum. Benim görüşüme göre, bildirim bu sinyali dinlerken ve buna göre tepki verirken, "bildirim-ses-ses-ortamı" şeklinde bir sinyal çıkması daha anlamlı olur. Gönderme / alma özel olmaktan ziyade halksa, daha fazla esnekliğe ve verimliliğe izin vermez miydi? Örneğin, "bildirim-ses-ses-ortamı" için bir genel sinyal varsa, bu sinyalleri dinleyebilir (rakip uygulamaların varlığına izin verir) ve geliştiriciler sadece bir sinyal alırken ve ele alırken sinyal gönderme ile ilgili olmak zorundadır, bildiren uygulamanın işi (veya bu sinyallere ihtiyaç duyan herhangi bir program) olacaktır.

  3. Ben sadece Dbus için yeni ve daha fazla bilgi edinmek için bazı uygulama geliştirmek için, Python üzerinde Dbus ile çalışırken öğrenmek istiyorum. dbus-python öğreticisini gördüm ve tüm sinyallerin nasıl dinleneceğini öğretiyor (ne arabirim ne de yol belirterek, vb.) Ancak, dbus-monitor gibi, çağrıldıklarında yöntemleri nasıl izleyebiliriz?

Bunun nasıl çalıştığını öğretecek sabrınız varsa, rica ederim.

    
sordu Benjamin 01.05.2011 10:18

2 cevap

21

D-Bus girişi

  • D-Bus, hizmetler arasında iletişim kurmak için araçlar sağlar. Hizmetler anonim olabilir (yalnızca aşağıdaki adresle belirtilir: 1.6) ve hizmetler, org.freedesktop.Notifications veya org.freedesktop.NetworkManager gibi iyi bilinen adlar 'ı kullanabilir. Günlüklerde görebileceğiniz gönderici ve varış noktası hizmetlerdir. "Boş hedef", yayın anlamına gelir: tüm hizmetlere teslimat.

  • Bir servis, bir veya birkaç nesne veriyoluna veri yollayabilir. Nesneler nesne yolları , /org/freedesktop/NetworkManager/ActiveConnection/1 veya /org/ayatana/menu/DA00003 gibi. Nesne yolları, dosya sistemi yolları gibi ayırıcı olarak eğik çizgi kullanır.

  • Her nesne bir veya birkaç arabirimi destekleyebilir. Bir arabirim, ortak olarak üyeler (OOP arabirimine çok benzer) olarak bilinen bir dizi yöntem ve sinyalden başka bir şey değildir. Yöntem ve sinyaller sabit imzalara sahiptir. Üyeler her zaman iyi bilinen arayüz adları içinde isimlendirilir.

  • Yayınlandıktan sonra, iyi bilinen isimler asla değişmez .

  • Herhangi bir servis başka bir servisin sinyallerine bağlanabilir ve zaman uyumsuz yöntemlerini çağırabilir. Herhangi bir servis sinyal verebilir.

Sinyaller

Şimdi belirli sorularınız için.

signal sender=:1.1948 -> dest=(null destination) serial=1829990 path=/org/ayatana/menu/DA00003; interface=org.ayatana.dbusmenu; member=ItemPropertyUpdated
int32 23
string "enabled"
variant boolean true

Evet, haklısın, bu bir işaret. Hizmet :1.1948 tarafından yayınlandı ve "self" nesnesi /org/ayatana/menu/DA00003 . Sinyal ItemPropertyUpdated arabiriminde tanımlanan org.ayatana.dbusmenu değerine sahiptir (C ++ 'da org.ayatana.dbusmenu::ItemPropertyUpdated gibi). Seri, sanırım, otobüsteki olayın benzersiz bir tanımlayıcısıdır.

Ardından sinyal argümanlarını görüyoruz. arayüz dokümanlarına göre İlk int32 bağımsız değişkeni bir öğenin kimliğidir, ikinci dizenin özellik adı ve üçüncü varyantı özellik değeridir. Yani, /org/ayatana/menu/DA00003 nesnesi bize bildiriyor öğe no # 23, enabled özelliğini true olarak değiştirdi.

Sinyaller hakkında başka bir örnek:

signal sender=:1.1602 -> dest=(null destination) serial=20408 path=/im/pidgin/purple/PurpleObject; interface=im.pidgin.purple.PurpleInterface; member=SendingChatMsg
   int32 47893
   string "test"
   uint32 1
signal sender=:1.1602 -> dest=(null destination) serial=20409 path=/im/pidgin/purple/PurpleObject; interface=im.pidgin.purple.PurpleInterface; member=IrcSendingText
   int32 64170
   string "PRIVMSG #chat :test

Pidgin'i bir IRC kanalına kullanarak bir metin mesajı "test" gönderdim ve /im/pidgin/purple/PurpleObject , im.pidgin.purple.PurpleInterface arabirimi altında iki sinyal yayınladı: ilk önce genel SendingChatMsg , ardından daha spesifik IrcSendingText .

Yöntem

Şimdi yöntemler. Yöntemler, D-Bus nesnelerini bir şey yapmasını istemek ya da bazı sorgulama ve veriyi döndürmek için bir yoldur. Klasik OOP yöntemlerine oldukça benzerler, ancak D-Bus yöntemleri eşzamansız olarak adlandırılır.

Programlı olarak D-Bus yöntemini çağıralım.

import dbus, dbus.proxies

#-- connect to the session bus (as opposed to the system bus)
session = dbus.SessionBus()

#-- create proxy object of D-Bus object
obj_proxy = dbus.proxies.ProxyObject(conn=session,
         bus_name="org.freedesktop.Notifications",     #-- name of the service we are retrieving object from
         object_path="/org/freedesktop/Notifications") #-- the object path

#-- create proxy object of the D-Bus object wrapped into specific interface
intf_proxy = dbus.proxies.Interface(obj_proxy, "org.freedesktop.Notifications")

#-- lastly, create proxy object of the D-Bus method
method_proxy = intf_proxy.get_dbus_method("Notify")

#-- ... and call the method
method_proxy("test from python",
             dbus.UInt32(0),
             "bluetooth",     #-- icon name
             "Notification summary",
             "Here goes notification body",
             [], {},
             5) #-- timeout

Bağımsız değişkenlere, özellikle simge adına dikkat edin. Örneğinizde "notification-audio-volume-medium" , orta güçlü ses hoparlörünün simgesiydi.

Özel hizmetler

Kendi D-Bus hizmetlerinizi çalıştırmak, kendi D-Bus nesnelerini dışa aktarmak ve kendi D-Bus arabirimlerinizi kendi yöntemleriniz ve sinyallerinizle tanımlamak kesinlikle mümkün. Bu, genel konsepti kavradıktan ve dbus modül belgelerini okuduktan sonra Python'da kolayca yapılabilir. % Co_de%

    
verilen cevap ulidtko 01.05.2011 14:31
10

Ayrıca masaüstü bildirimlerini bir python betiğiyle dbus üzerinden toplamak için bir çözüm arıyordum. Bu soru googling ile en yakın olduğum oldu, ancak notify-osd için bir yedek yazmak bir overkill gibi görünüyordu:)

son bildirimler uygulama kaynaklarına baktığımda dbus mesajlarını nasıl izleyeceğime dair bazı ipuçları aldım ve işte python uygulaması I geldi:

import gtk
import dbus
from dbus.mainloop.glib import DBusGMainLoop

def filter_cb(bus, message):
    # the NameAcquired message comes through before match string gets applied
    if message.get_member() != "Notify":
        return
    args = message.get_args_list()
    # args are
    # (app_name, notification_id, icon, summary, body, actions, hints, timeout)
    print("Notification from app '%s'" % args[0])
    print("Summary: %s" % args[3])
    print("Body: %s", args[4])


DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_match_string(
    "type='method_call',interface='org.freedesktop.Notifications',member='Notify'")
bus.add_message_filter(filter_cb)
gtk.main()

Bunun birilerine yardımcı olacağını umuyorum, çünkü dbus mesajlarının izlenmesine ilişkin çok sayıda basit python örneği yoktur.

    
verilen cevap Keto 27.05.2012 14:23

Etiketlerdeki diğer soruları oku