|
D-Bus的方式在移動手機(jī)操作系統(tǒng)中非常重要,包括Maemo,Moblin等以Linux為基礎(chǔ)的操作系統(tǒng)。估計(jì)Andriod也大量使用。D-Bus的相關(guān)學(xué)習(xí)資料見: http://www./wiki/Software/dbus 。
消息通過D-Bus在進(jìn)程間傳遞。有四類消息:
一、Method call消息:將觸發(fā)對象的一個method
二、Method return消息:觸發(fā)的方法返回的結(jié)果 三、Error消息:觸發(fā)的方法返回一個異常 四、Signal消息:通知,可以看作為事件消息。 一個消息有消息頭header,里面有field,有一個消息體body,里面有參數(shù)arguments。消息頭包含消息體的路由信息,消息體就是凈荷payload。頭字段可能包括發(fā)送者的bus名,目的地的bus名,方法或者signal名等等,其中一個頭字段是用于描述body中的參數(shù)的類型,例如“i”標(biāo)識32位整數(shù),"ii”表示凈荷為2個32為整數(shù)。
發(fā)送Method call消息的場景
一個method call消息從進(jìn)程A到進(jìn)程B,B將應(yīng)答一個method return消息或者error消息。在每個call消息帶有一個序列號,應(yīng)答消息也包含同樣的號碼,使之可以對應(yīng)起來。他們的處理過程如下:
•如果提供proxy,通過觸發(fā)本地一個對象的方法從而觸發(fā)另一個進(jìn)程的遠(yuǎn)端對象的方法。應(yīng)用調(diào)用proxy的一個方法,proxy構(gòu)造一個method call消息發(fā)送到遠(yuǎn)端進(jìn)程。
•對于底層的API,不使用proxy,應(yīng)用需要自己構(gòu)造method call消息。 •一個method call消息包含:遠(yuǎn)端進(jìn)程的bus name,方法名字,方法的參數(shù),遠(yuǎn)端進(jìn)程中object path,可選的接口名字。 •method call消息發(fā)送到bus daemon •bus daemon查看目的地的bus name。如果一個進(jìn)程對應(yīng)這個名字,bus daemon將method call消息發(fā)送到該進(jìn)程中。如果沒有發(fā)現(xiàn)匹配,bus daemon創(chuàng)建一個error消息作為應(yīng)答返回。 •進(jìn)程接收后將method call消息分拆。對于簡單的底層API情況,將立即執(zhí)行方法,并發(fā)送一個method reply消息給bus daemon。對于高層的API,將檢查對象path,interface和method,觸發(fā)一個native object的方法,并將返回值封裝在一個method reply消息中。 •bus daemon收到method reply消息,將其轉(zhuǎn)發(fā)到原來的進(jìn)程中 •進(jìn)程查看method reply消息,獲取返回值。這個響應(yīng)也可以標(biāo)識一個error的殘生。當(dāng)使用高級的捆綁,method reply消息將轉(zhuǎn)換為proxy方法的返回值或者一個exception。 Bus daemon保證message的順序,不會亂序。例如我們發(fā)送兩個method call消息到同一個接受方,他們將按順序接受。接收方并不要求一定按順序回復(fù)。消息有一個序列號了匹配收發(fā)消息。 發(fā)送Signal的場景
signal是個廣播的消息,不需要響應(yīng),接收方向daemon注冊匹配的條件,包括發(fā)送方和信號名,bus守護(hù)只將信號發(fā)送給希望接受的進(jìn)程。處理流程如下:
•一個signal消息發(fā)送到bus daemon。
•signal消息包含發(fā)布該信號的interface名字,signal的名字,進(jìn)程的bus名字,以及參數(shù)。 •任何進(jìn)程都可以注冊的匹配條件(match rules)表明它所感興趣的signal??偩€有個注冊match rules列表。 •bus daemon檢查那些進(jìn)程對該信號有興趣,將信號消息發(fā)送到這些進(jìn)程中。 •收到信號的進(jìn)程決定如何處理。如果使用高層的捆綁,一個porxy對象將會十分一個native的信號。如果使用底層的API,進(jìn)程需要檢查信號的發(fā)送發(fā)和信號的名字決定如果進(jìn)行處理。 Introspection D-Bus對象可能支持一個接口org.freedesktop.DBus.Introspectable。該接口有一個方法Introspect,不帶參數(shù),將返回一個XML string。這個XML字符串描述接口,方法,信號。
D-Bus提供兩個命令dbus-monitor,可以查看bus,dbus-send命令,可以發(fā)送消息,可以用man來檢查:
dbus-send [--system | --session] --type=method_call(或者是signal,缺省是signal) --print-reply --dest=連接名 對象路徑 接口名.方法名 參數(shù)類型:參數(shù)值 參數(shù)類型:參數(shù)值
我們通過這個接口.方法來更好地了解D-Bus。我們使用到一個方法ListNames來查看:
[wei@wei-desktop ~]$ dbus-send --print-reply --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames
method return sender=org.freedesktop.DBus -> dest=:1.75 reply_serial=2 array [ string "org.freedesktop.DBus" string ":1.7" string "org.freedesktop.Notifications " string "org.freedesktop.Telepathy.Client.EmpathyMoreThanMeetsTheEye" ... ... string ":1.6" string ":1.19" ] 例如其中有org.freedesktop.Notifications這樣一個Name,我們希望進(jìn)一步查看
[wei@wei-desktop ~]$ dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications / org.freedesktop.DBus.Introspectable.Introspect method return sender=:1.19 -> dest=:1.79 reply_serial=2 string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www./standards/dbus/1.0/introspect.dtd"> <node> <node name="org"/> </node> " 例如Node名字,表明路徑,從/org開始 [wei@wei-desktop ~]$ dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications /org org.freedesktop.DBus.Introspectable.Introspect method return sender=:1.19 -> dest=:1.80 reply_serial=2 string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www./standards/dbus/1.0/introspect.dtd"> <node> <node name="freedesktop"/> <node name="moblin"/> </node> " Node名字,表明路徑,有從/org/freedesktop開始
[wei@wei-desktop ~]$ dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop org.freedesktop.DBus.Introspectable.Introspect method return sender=:1.19 -> dest=:1.81 reply_serial=2 string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www./standards/dbus/1.0/introspect.dtd"> <node> <node name="Notifications"/> </node> "
Node名字,表明路徑,有從/org/freedesktop/Notifications開始,可以獲取這個接口有什么method和singnal。
[wei@wei-desktop ~]$ dbus-send --print-reply --type=method_call --dest=org.freedesktop.Notifications /org/freedesktop/Notifications org.freedesktop.DBus.Introspectable.Introspect method return sender=:1.19 -> dest=:1.82 reply_serial=2 string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www./standards/dbus/1.0/introspect.dtd"> <node> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg name="data" direction="out" type="s"/> </method> </interface> <interface name="org.freedesktop.DBus.Properties"> <method name="Get"> <arg name="interface" direction="in" type="s"/> <arg name="propname" direction="in" type="s"/> <arg name="value" direction="out" type="v"/> </method> <method name="Set"> <arg name="interface" direction="in" type="s"/> <arg name="propname" direction="in" type="s"/> <arg name="value" direction="in" type="v"/> </method> <method name="GetAll"> <arg name="interface" direction="in" type="s"/> <arg name="props" direction="out" type="a{sv}"/> </method> </interface> <interface name="org.freedesktop.Notifications"> <method name="GetServerInformation"> <arg name="name" type="s" direction="out"/> <arg name="vendor" type="s" direction="out"/> <arg name="version" type="s" direction="out"/> </method> <method name="GetCapabilities"> <arg name="caps" type="as" direction="out"/> </method> <method name="CloseNotification"> <arg name="id" type="u" direction="in"/> </method> <method name="Notify"> <arg name="app_name" type="s" direction="in"/> <arg name="id" type="u" direction="in"/> <arg name="icon" type="s" direction="in"/> <arg name="summary" type="s" direction="in"/> <arg name="body" type="s" direction="in"/> <arg name="actions" type="as" direction="in"/> <arg name="hints" type="a{sv}" direction="in"/> <arg name="timeout" type="i" direction="in"/> <arg name="return_id" type="u" direction="out"/> </method> <signal name="NotificationClosed"> <arg type="u"/> <arg type="u"/> </signal> </interface> </node> " 本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/flowingflying/archive/2010/03/24/5412711.aspx
|
|
|