D-Bus
D-Bus (Desktop Bus) je svobodný software poskytující aplikacím jednoduchý způsob jak vzájemně komunikovat. Je vyvíjen jako součást projektu freedesktop.org.
Vývojář | Red Hat |
---|---|
Aktuální verze | 1.13.18 (2. července 2020) |
Vyvíjeno v | C |
Typ softwaru | knihovna, svobodný software, síťový protokol a message-oriented middleware |
Licence | GPLv2 Academic Free License |
Web | www |
Některá data mohou pocházet z datové položky. |
Návrh D-Bus byl významně ovlivněn systémem DCOP používaným v pracovním prostředí KDE. Ve čtvrtém vydání KDE 4 byl DCOP plně nahrazen systémem D-Bus. V současnosti už je tento systém také implementován v Qt 4, GNOME, Windows, Maemo a OLPC XO-1. V pracovním prostředí GNOME postupně nahrazuje zastaralý systém Bonobo.
Úvod
D-Bus umožňuje programům zaregistrovat si služby, které budou nabízeny ostatním aplikacím. Rovněž jej mohou využívat klientské programy, aby zjistily, jaké služby jsou dostupné. Program se může také zaregistrovat pro očekávaní událostí přímo od kernelu, například hot swapping.
D-Bus je implementován jako démon. Uživatel jej může spustit v několika instancích, kterým se většinou říká kanál. Většinou se jedná o systémovou instanci, která je jedinečná v rámci celého systému a privátní instance, které jsou vytvářeny pro každého přihlášeného uživatele. Na systémovou instanci jsou kladena přísná bezpečnostní omezení, proto jsou potřebné privátní instance.
Hlavní poslání systémové instance spočívá v doručování signálů od HAL démona příslušným procesům. Privátní instance umožňují neomezenou komunikaci mezi aplikacemi v rámci uživatelského přihlášení.
Architektura
D-Bus je mezi-procesový komunikační systém skládající se ze tří vrstev:
- knihovna libdbus, která umožňuje propojení dvou aplikací a vzájemnou výměnu zpráv
- démon pro rozesílání zpráv, založený na libdbus, ke kterému se mohou připojovat aplikace; démon umí doručit zprávu od jedné aplikace žádné nebo více aplikacím
- obalové knihovny založené na příslušném aplikačním frameworku
D-Bus je určen pro dva specifické případy:
Mechanismus
Každá aplikace používající D-Bus obsahuje objekty, které se většinou (ale ne nezbytně) mapují na GObject, QObject, C++ objekty, nebo Perl, Python objekty. Objekt je v tomto smyslu chápán spíše jako instance než datový typ. Zprávy přijímané přes D-Bus jsou zasílány konkrétnímu objektu, nikoliv celé aplikaci. V tomto ohledu se D-Bus podobá softwarovým komponentám. Uživateli se objekt jeví, jako kdyby byl přenášen serializován přes IPC spojení bez ohledu na to, zda na druhé straně objekt skutečně existuje.
Aby zprávy mohly určit svůj cílový objekt, musí být zaveden způsob jak se na objekty odkazovat. V mnoha programovacích jazycích se k tomuto účelu využívají reference nebo ukazatelé. Nicméně tyto reference jsou implementovány jako relativní adresy v rámci adresového paměťového prostoru aplikace a z toho důvodu nemohou být předávány.
D-Bus řeší tento problém tak, že každému objektu přiřadí jedinečné jméno. To má tvar cesty v souborovém systému a objekt může být pojmenován například: /org/kde/kspread/sheets/3/cells/4/5. Jména by měla být snadno čitelná, ale vývojáři si mohou vytvořit i objekt pojmenovaný /com/mycompany/c5yo817y0c1y1c5b, pokud má význam v rámci aplikace.
Jména objektů jsou v rámci D-Bus rozlišena pomocí jmenných prostorů, aby se zajistilo, že různé moduly se zdrojovými kódy budou oddělené. Jmenné prostory často začínají předponou vytvořenou z jména vývojářovy domény (např. /org/kde).
Implementace
- Freedesktop.org D-Bus, referenční implementace
- kdbus, kernel space implementace pro Linux
- windbus, implementace pro Windows
- NDesk Managed D-Bus, určená pro .NET, první nezávislá implementace podle: cleanroom design[1]
- D-Bus Java, evolved[2] z rozšíření pro Java vznikla samostatná implementace
Příklady
Mnoho jazyků umožňuje vysokoúrovňový přístup pro D-Bus a skrývají implementační detaily, optimalizace, marshalling, řazení do fronty a dispatching. Ve staticky typovaných jazycích jako je C# nebo Java musí být nejprve nadefinováno nebo exportováno rozhraní. Pro přístup k zařízení HAL bude částečný popis rozhraní v jazyce C# vypadat následovně:
Pro rozhraní zařízení:
/* atribut rozhraní se používá k označení jména D-Bus rozhraní */
[Interface ("org.freedesktop.Hal.Device")]
public interface Device
{
/* definice událostí mapovaných na D-Bus signály */
event PropertyModifiedHandler PropertyModified;
/* vlastnosti a volání metod mapované na D-Bus volání */
/* D-Bus typový systém je schopný reprezentovat obecné slovníky */
IDictionary<string, object> AllProperties { get; }
/* další metody a signály jsou vynechány kvůli přehlednosti */
}
/* D-Bus podporuje atributové struktury */
public struct PropertyModification
{
public string Key;
public bool Added;
public bool Removed;
}
public delegate void PropertyModifiedHandler (int modificationsLength,
PropertyModification[] modifications);
A pro správce zařízení:
[Interface ("org.freedesktop.Hal.Manager")]
public interface Manager
{
/* definice událostí mapovaných na D-Bus signály */
event Action<Device> DeviceAdded;
event Action<Device> DeviceRemoved;
/* vlastnosti a volání metod mapované na D-Bus volání */
Device[] AllDevices { get; }
bool DeviceExists (Device udi);
bool DeviceExists (ObjectPath udi);
Device[] FindDeviceStringMatch (string key, string value);
Device[] FindDeviceByCapability (string capability);
void Remove (Device udi);
/* další metody a signály jsou vynechány kvůli přehlednosti */
}
Jakmile jsou rozhraní definována, programátor si může obstarat proxy objekty, které odpovídají jejich vzdáleným protějškům a nakládat s nimi jako by se nacházely v lokálním adresním prostoru:
/* žádost o proxy objekty pro správce zařízení ze systému zpráv */
Manager mgr = Bus.System.GetObject<Manager> ("org.freedesktop.Hal",
new ObjectPath ("/org/freedesktop/Hal/Manager"));
/* označíme všechna zařízení */
foreach (Device dev in mgr.AllDevices) {
/* print the path of the object */
Console.WriteLine (dev.ToString ());
/* zavěšení na signál PropertyModified zařízení */
dev.PropertyModified += delegate (int modificationsLength,
PropertyModification[] modifications) {
/* když se zmení vlastnosti, vytiskne se změna */
Console.WriteLine ("Properties changed on device {0}:", dev);
foreach (PropertyModification modification in modifications)
Console.WriteLine (modification.Key);
};
}
Reference
- Alp Toker, D-Bus mailing list (2006)
- Matthew Johnson, D-Bus mailing list (2007)
Externí odkazy
- Freedesktop.org D-Bus (anglicky)
- Examples of D-Bus usage from console (anglicky)
- Popis D-Bus od Petra Macha