dbus介绍文档翻译

This document(关于此文档)

The following text is not a tutorial or a reference. It will not show you how to use D-Bus (yet). It won't tell you how to install D-Bus or how to program for it.

这不是一篇教程或者参考…

What you will find here is an explanation what D-Bus really is, what the concepts behind it are and how they fit together, and what jargon you'll need to know to understand it all. There will be no unnecessary technical detail, and no assumptions about what language you like to program in. The idea is that you can read this before you move on to tutorials or how-to guides for whatever it is you want to use D-Bus for.

您将在此处找到什么是 D-Bus 真正含义的解释*,它背后的概念是*什么以及它们如何组合在一起,以及您需要知道哪些术语才能理解这一切。没有不必要的技术细节,也没有关于您喜欢用哪种语言编程的假设。我们的想法是,您可以在继续阅读教程或操作指南之前先阅读本文,了解您想使用 D-Bus 的任何内容为了。

Reading all this first can be useful even if you have a good tutorial to work with. There's a long list of words that have special meanings in the D-Bus world, and not all of them are completely standardized. In this document we try to explain them from the ground up so you won't run into unexplained terms that will only become clear later. We'll also try to give an overview of how different people's views of D-Bus overlap and differ. A perfectly good explanation written from the perspective of one particular programming language can sometimes mislead a new user, or even an experienced user, when using another language.

即使您有一个很好的教程可以使用,首先阅读所有这些内容也会很有用。在 D-Bus 世界中有一长串具有特殊含义的词,并不是所有的词都完全标准化。在本文档中,我们尝试从头开始解释它们,这样您就不会遇到无法解释的术语,这些术语只会在以后变得清晰。我们还将尝试概述不同人对 D-Bus 的看法如何重叠和不同。当使用另一种语言时,从一种特定编程语言的角度编写的完美解释有时会误导新用户,甚至是有经验的用户。

Introduction to D-Bus(D-Bus介绍)

D-Bus is an inter-process communication mechanism—a medium for local communication between processes running on the same host. (Inter-host connects may be added in the future, but that is not what D-Bus is meant for). D-Bus is meant to be fast and lightweight, and is designed for use as a unified middleware layer underneath the main free desktop environments.

D-Bus 是一种进程间通信机制——运行在同一主机上的进程之间进行本地通信的媒介。(将来可能会添加主机间连接,但这不是 D-Bus 的用途)。D-Bus 旨在快速和轻量级,旨在用作主要免费桌面环境下的统一中间件层。

If you're familiar with many communication mechanisms, here's a quick rundown of this one. Unlike more heavyweight conventional messaging middleware, D-Bus is non-transactional. It is stateful and connection-based, however, making it "smarter" than low-level message-passing protocols such as UDP. On the other hand, it does carry messages as discrete items—not continuous streams of data as is the case with TCP. Both one-to-one messaging and publish/subscribe communication are supported.

如果您熟悉许多通信机制,下面是对这个机制的简要介绍。与更重量级的传统消息传递中间件不同,D-Bus 是非事务性的。然而,它是有状态的和基于连接的,使其比低级消息传递协议(如 UDP)“更智能”。另一方面,它确实将消息作为离散项目传送——而不是像 TCP 那样的连续数据流。支持一对一消息传递和发布/订阅通信。

D-Bus has a structured view of the data it carries, and deals with data in binary form: integral numbers of various widths, floating-point numbers, strings, compound types, and so on. Because data is not just "raw bytes" to D-Bus, messages can be validated and ill-formed messages rejected. In technical terms, D-Bus behaves as an RPC mechanism and provides its own marshaling.

D-Bus 对其承载的数据具有结构化视图,并以二进制形式处理数据:各种宽度的整数、浮点数、字符串、复合类型等。由于数据不仅仅是 D-Bus 的“原始字节”,因此可以验证消息并拒绝格式错误的消息。在技术方面,D-Bus 表现为一种 RPC 机制并提供自己的编组。

Language Bindings(语言绑定)

Application Programming Interfaces for D-Bus, or bindings, are available in several languages—typically one per language, but not necessarily. Each presents its own API as suits the language, hiding the details of working with D-Bus from the programmer to different extents. The ideal is to fit the D-Bus API into the native language and libraries as naturally as possible.

D-Bus 的应用程序编程接口或绑定有多种语言版本——通常每种语言一种,但不一定。每个都提供了适合语言的自己的 API,在不同程度上对程序员隐藏了使用 D-Bus 的细节。理想的情况是尽可能自然地将 D-Bus API 融入本地语言和库中。

Using D-Bus should feel more like object-oriented programming than like communication. In some bindings, a programmer may hardly notice that D-Bus is there at all. When that happens, a program that uses D-Bus to communicate will for the most part look as if the counterparts it communicates with were regular components (libraries, modules, packages, objects, functions—whatever the language uses) of the program itself. This is also why some aspects of D-Bus that may seem very basic can differ greatly depending on programming language.

使用 D-Bus 应该感觉更像是面向对象的编程而不是通信。在某些绑定中,程序员可能根本不会注意到 D-Bus 的存在。当这种情况发生时,使用 D-Bus 进行通信的程序在大多数情况下看起来就好像它与之通信的对应部分是程序本身的常规组件(库、模块、包、对象、函数——无论使用什么语言)。这也是为什么 D-Bus 的某些看似非常基本的方面可能会因编程语言而有很大差异。

D-Bus bindings are available for an increasing number of languages. There is a low-level C binding, but that is probably too detailed and cumbersome for anything but writing other bindings. A more practical C binding is based on GLib. There are also Java, Perl and Python bindings. There are also dbus ?notes and examples, and so on.

D-Bus 绑定可用于越来越多的语言。有一个低级别的 C 绑定,但除了编写其他绑定之外,这可能太详细和繁琐了。更实用的 C 绑定基于GLib。还有JavaPerlPython绑定。还有dbus 笔记和例子,等等。

Buses(总线)

There are two major components to D-Bus: a point-to-point communication dbus library, which in theory could be used by any two processes in order to exchange messages among themselves; and a dbus daemon. The daemon runs an actual bus, a kind of "street" that messages are transported over, and to which any number of processes may be connected at any given time. Those processes connect to the daemon using the library, and it probably wouldn't make much sense to use the library for anything else. We'll be looking mostly at the situation where applications (or more generally, clients) connect to a full-blown bus.

D-Bus 有两个主要组件:一个点对点通信*dbus库,理论上可以被任何两个进程用来在它们之间交换消息;和一个dbus守护进程。* 守护进程运行一个实际的*总线,*一种传输消息的“街道”,在任何给定时间可以连接任意数量的进程。这些进程使用库连接到守护程序,将库用于其他任何事情可能没有多大意义。我们将主要关注应用程序(或更一般地说,客户端)连接到成熟总线的情况。

Multiple buses may be active simultaneously on a single system. D-Bus was first built to replace the CORBA-like component model underlying the GNOME desktop environment. Similar to DCOP (which is used by KDE), D-Bus is set to become a standard component of the major free desktop environments for GNU/Linux and other platforms. A GNOME environment normally runs two kinds of buses: a single system bus for miscellaneous system-wide communication, e.g. notifications when a new piece of hardware is hooked up; and a session bus used by a single user's ongoing GNOME session. A session bus normally carries traffic under only a single user identity, but D-Bus is aware of user identities and does support flexible authentication mechanisms and access controls. The system bus may see traffic from and to any number of user identities.

多条总线可以在单个系统上同时处于活动状态。D-Bus 最初是为了取代 GNOME 桌面环境下的类 CORBA 组件模型而构建的。与 DCOP(由 KDE 使用)类似,D-Bus 将成为 GNU/Linux 和其他平台的主要免费桌面环境的标准组件。GNOME 环境通常运行两种总线:用于各种系统范围通信的单一系统总线,例如连接新硬件时的通知;和会话总线由单个用户正在进行的 GNOME 会话使用。会话总线通常仅在单个用户身份下承载流量,但 D-Bus 知道用户身份并支持灵活的身份验证机制和访问控制。系统总线可以看到来自和去往任意数量用户身份的流量。

Addresses(地址)

Every bus has an address describing how to connect to it. A bus address will typically be the filename of a Unix-domain socket such as "/tmp/.hiddensocket," but it may also be a TCP port where a bus daemon is listening on an IP-domain socket, or conceivably a descriptor for some other low-level communications scheme. The details of how to hook up to the bus daemon are, of course, completely hidden from the client process by the dbus library. We'll just say that a client process opens and uses a connection to the bus.

每条总线都有一个描述如何连接它的地址。总线地址通常是 Unix 域套接字的文件名,例如“ ” /tmp/.hiddensocket,但它也可能是一个 TCP 端口,总线守护程序在该端口上侦听 IP 域套接字,或者可能是其他一些低级套接字的描述符通讯方案。当然,dbus 库对客户端进程完全隐藏了如何连接到总线守护进程的细节。我们只会说客户端进程打开并使用到总线的连接

Configuration and Startup(配置和启动)

Bus daemons are started using the dbus-launch command, which in turn runs dbus-daemon. Both take an option --config-file option to indicate a configuration file describing the bus being started. The standard buses have /etc/dbus-1/system.conf and /etc/dbus-1/session.conf as their respective configuration files.Configuration files are in a simple XML-based format called busconfig.

总线守护进程使用该dbus-launch命令启动,该命令依次运行dbus-daemon. 两者都采用选项--config-file选项来指示描述正在启动的总线的配置文件。标准总线有/etc/dbus-1/system.conf/etc/dbus-1/session.conf作为它们各自的配置文件。

配置文件采用简单的基于 XML 的格式,称为busconfig。

Connections(连接)

Every connection to a bus can be addressed on that bus under one or more names. These names are known as the connection's bus names. (Note that bus names are the names of connections on the bus, not names of buses.) Bus names consist of a series of identifiers separated by dots, e.g. "com.acme.Foo" and the identifiers themselves may contain letters, digits, dashes, and underscores. The connection is said to own its bus names.

到总线的每个连接都可以在该总线上以一个或多个名称寻址。这些名称称为连接的总线名称。 (请注意,总线名称是总线上的连接名称,而不是总线名称。)总线名称由一系列由点分隔的标识符组成,例如“ com.acme.Foo”,标识符本身可能包含字母、数字、破折号和下划线。据说该连接拥有其总线名称。

When a connection is set up, the bus immediately assigns it an immutable bus name that it will retain for as long as the bus exists. This bus name is called a unique connection name, because no other connection will ever have that same name on the same bus--even if the connection is closed down and other ones are created. It can be recognized by the fact that it starts with a colon, which is otherwise not possible: ":34-907" (the other parts of the name have no particular meaning).

建立连接后,总线会立即为其分配一个不可变的总线名称,只要总线存在,它就会保留该名称。此总线名称称为*唯一连接名称,*因为在同一总线上没有其他连接具有相同的名称——即使连接已关闭并创建了其他连接。可以通过它以冒号开头的事实来识别,否则这是不可能的:“ :34-907”(名称的其他部分没有特别的含义)。

A connection may also request additional names, e.g. to offer services under well-known names that are agreed upon by convention. These names must consist of two or more dot-separated elements: "com.acme.PortableHole". Only one connection can hold a given name on the bus at any time, but except for unique connection names, bus names can be relinquished and grabbed by other clients. (Whether a client currently holding it is willing to give it up is, of course, another question, but there are ways of arbitrating this.)

连接还可以请求附加名称,例如以约定俗成的众所周知的名称提供服务。这些名称必须由两个或多个以点分隔的元素组成:“ com.acme.PortableHole”。任何时候在总线上只有一个连接可以拥有一个给定的名称,但是除了唯一的连接名称之外,总线名称可以被其他客户端放弃和获取。(目前持有它的客户是否愿意放弃它当然是另一个问题,但有仲裁的方法。)

Object Model(对象模型)

Message exchange on protocols like TCP or UDP is symmetric; in those examples, data is always transferred from one "port" to another. D-Bus presents a more sophisticated model where the sending and the receiving side of a message are never quite of the same type.

TCP 或 UDP 等协议上的消息交换是对称的;在这些例子中,数据总是从一个“端口”传输到另一个“端口”。D-Bus 提供了一个更复杂的模型,其中消息的发送端和接收端从来都不是完全相同的类型。

In the following we'll borrow from object-oriented terminology. Many terms such as "object" and "method" have more specific meanings in the context of D-Bus, and may have nothing to do with whatever else is going on in client applications. We'll write these terms in italics when they are introduced. All of them are used here only in their D-Bus specific sense, never for their general meanings.

下面我们将借用面向对象的术语。许多术语如“对象”和“方法”在 D-Bus 的上下文中具有更具体的含义,并且可能与客户端应用程序中发生的其他事情无关。介绍这些术语时*,我们会用斜体*写出这些术语。所有这些都只在 D-Bus 特定意义上使用,从不用于它们的一般含义。

Objects(对象)

One end of any exchange on a bus will always be a communications endpoint that in D-Bus parlance is called an object. An object is created by a client process and exists within the context of that client's connection to the bus. The object is a way for the client process to offer its services on the bus--but one client may create any number of objects.

总线上任何交换的一端将始终是一个通信端点,在 D-Bus 术语中称为对象。 对象由客户端进程创建并存在于该客户端与总线的连接的上下文中。对象是客户端进程在总线上提供其服务的一种方式——但是一个客户端可以创建任意数量的对象。

The bus imposes an object-centric view of communications, where any message carried by the bus is of one of three kinds:	Requests sent to objects by client processes.	Replies to requests, going from an object back to a requesting process.	One-way messages emanating from objects, broadcast to any connected clients that have registered an interest in them. Thus at a higher level of abstraction, the bus supports two forms of communication that we could call "1:1 request-reply" going to an object, and "1:n publish-subscribe" coming from an object.

总线强加了以对象为中心的通信视图,其中总线承载的任何消息都属于以下三种类型之一:

  1. 客户端进程发送到对象的请求。
  2. 对请求的回复,从一个对象返回到一个请求进程。
  3. 从对象发出的单向消息,广播到任何已注册对它们感兴趣的连接客户端。因此,在更高的抽象层次上,总线支持两种形式的通信,我们可以称之为“ 1:1请求-回复”到一个对象,以及“ 1:n发布-订阅”来自一个对象。
Every bus has at least one object, representing the bus itself. Clients can obtain information about the status of the bus by sending requests to this object. As you'll see later on, it represents the bus in other useful ways as well.

每条总线至少有一个对象,代表总线本身。客户端可以通过向该对象发送请求来获取有关总线状态的信息。正如您稍后将看到的,它也以其他有用的方式表示总线。

Proxies(代理)

Objects on the bus can be accessed through references that we call proxies. We call them that because a proxy is a local representation inside your own program of an object that is really accessed through the bus, and typically lives outside your program: you literally access the object "by proxy." Whether you need to know the difference between an object and a proxy depends on how you talk to D-Bus. The Java binding hides the difference, making it look like you're dealing with the objects directly, but the GLib binding makes the existence of proxies very visible and even offers two kinds of proxies. A proxy exists only inside your client, and the details of how it works depend entirely on the binding you use.

总线上的对象可以通过我们称为代理的引用进行访问*。* 我们之所以这样称呼它们,是因为代理是您自己的程序内部对象的本地表示,该对象实际上是通过总线访问的,并且通常位于您的程序之外:您实际上是“通过代理”访问对象。您是否需要知道对象和代理之间的区别取决于您如何与 D-Bus 交谈。Java 绑定隐藏了差异,使您看起来像是在直接处理对象,但 GLib 绑定使代理的存在非常明显,甚至提供了两种代理。代理仅存在于您的客户端内部,其工作方式的详细信息完全取决于您使用的绑定。

Objects have names, also called paths because they look like Unix-style, slash-separated filesystem paths. An object that represents a particular cell in a particular spreadsheet might be called "/org/kde/kspread/sheets/3/cells/4/5", for instance. An object's name needs to be unique only within the context of its connection to the bus. To obtain a proxy to that spreadsheet cell, you would ask the bus to look up object /org/kde/kspread/sheets/3/cells/4/5 for you, to be found in the context of the spreadsheet's connection.

对象有名称,也称为*路径,*因为它们看起来像 Unix 风格的、斜线分隔的文件系统路径。例如,表示特定电子表格中特定单元格的对象可能称为“ /org/kde/kspread/sheets/3/cells/4/5”。对象的名称仅在其连接到总线的上下文中才需要是唯一的。要获得该电子表格单元格的代理,您需要让总线/org/kde/kspread/sheets/3/cells/4/5为您查找对象,以便在电子表格连接的上下文中找到。

Since any object "lives within" the context of a connection, it takes a combination of that connection's bus name and the object's own name to find it. Once you have found the object you want, if you'll be using it again soon, you'll usually want to keep a proxy to that object around as a variable in your program. That will save you having to look up the object time and again.

由于任何对象“存在于”连接的上下文中,因此需要结合该连接的总线名称和对象自己的名称才能找到它。一旦你找到了你想要的对象,如果你很快就会再次使用它,你通常希望在你的程序中保留一个该对象的代理作为变量。这将使您不必一次又一次地查找对象。

Some bindings' proxies may support failover. If you have a proxy to an object exported by some client connected to the bus under a well-known bus name, and that client disconnects (removing the object), reconnects under the same well-known name, and revivies the object, your own program may continue to use the proxy without ever noticing that the object went away for a while. Not all bindings support this, and of the two kinds of proxy in the GLib binding, only one does. It is also not always desirable, e.g. when subsequent operations on an object are meant to be a whole, and it's not acceptable for the object to be disbanded and later reinstituted without your noticing. In those cases, you may need to use a unique connection name in obtaining the proxy rather than a well-known one.

某些绑定的代理可能支持故障转移。 如果您有一个对象的代理,该对象由连接到总线的某个客户端以众所周知的总线名称连接到总线,并且该客户端断开连接(删除对象),以相同的众所周知的名称重新连接并恢复该对象,则您自己的程序可能会继续使用代理而不会注意到对象消失了一段时间。并非所有绑定都支持这一点,在 GLib 绑定中的两种代理中,只有一种支持。这也并不总是可取的,例如,当对一个对象的后续操作意味着是一个整体时,并且在您不注意的情况下解散该对象然后重新建立是不可接受的。在这些情况下,您可能需要在获取代理时使用唯一的连接名称而不是众所周知的连接名称。

Methods(方法)

When a client sends a request to an object, it sees this request as invoking a method on the object: the object is asked to perform a specific, named action. Normally, if a client tries to invoke a method on an object that the object does not provide, this will raise an error.

当客户端向对象发送请求时,它会将这个请求视为调用对象的方法:要求对象执行特定的命名操作。通常,如果客户端尝试在对象未提供的对象上调用方法,则会引发错误。

The method's definition may require certain information to be passed with the request as arguments (input parameters). For every request, a reply message carries the result back to the requester, along with either result data (output parameters) or, if the action could not be performed, exception information. Exceptions will contain at least an exception name and an error message.

方法的定义可能需要将某些信息作为参数(输入参数)与请求一起传递。对于每个请求,回复消息将结果连同结果数据(输出参数)或异常信息(如果操作无法执行)一起返回给请求者。异常将至少包含一个异常名称和一条错误消息。

Most D-Bus bindings make all this fit in with their environment's native mechanisms, hiding the finicky details of encapsulating parameters in messages and translating exception messages into exceptions (or whatever the native error-handling mechanism is). For example, passing a string argument to a method of some remote object will look to your program just like passing a string argument to a function in your own program. There is no need for tedious conversions and copying of the data into messages, and there is usually no need to concern yourself with the sending of the underlying message. The binding takes care of all that; the work of encapsulating your data into the messages is called marshalling.

大多数 D-Bus 绑定使所有这些都适合其环境的本机机制,隐藏了在消息中封装参数和将异常消息转换为异常(或任何本机错误处理机制)的繁琐细节。例如,将字符串参数传递给某个远程对象的方法在您的程序中看起来就像将字符串参数传递给您自己程序中的函数一样。不需要繁琐的转换和将数据复制到消息中,通常也不需要关心底层消息的发送。绑定负责所有这些;将数据封装到消息中的工作称为编组。

There is one interesting difference with conventional function calls: when sending a request to an object, you don't necessarily have to sit around and wait for a reply. In more complex programs you'll usually find other useful things to do until the method completes. You may want to be ready to handle user interaction, for example, or availability of data from a file or a network connection; you may even have multiple method invocations "in flight" and want to handle the results as they come in, rather than in some pre-defined order. This style of invocation, where you go on to do other things while waiting for an answer, is called asynchronous method invocation. If you use the simple call-and-wait style (synchronous invocation), any other messages that come in while you wait will be queued up and delivered to your program when it's ready for them.

与传统的函数调用有一个有趣的区别:当向对象发送请求时,您不必坐下来等待回复。在更复杂的程序中,在方法完成之前,您通常会发现其他有用的事情要做。您可能希望准备好处理用户交互,例如,或来自文件或网络连接的数据的可用性;您甚至可能有多个“正在运行”的方法调用,并希望在结果出现时对其进行处理,而不是按照某种预定义的顺序进行处理。这种在等待回答的同时继续做其他事情的调用方式称为异步方法调用。如果您使用简单的调用和等待样式(同步 调用),在您等待时进入的任何其他消息都将排队等候并在程序准备好接收它们时传送到您的程序。

Signals(信号)

The other form of communication also follows the object-oriented mould. Called signals, these one-way communications come from an object and go nowhere in particular. Client processes can register an interest in signals of a particular name coming from a particular object. Whenever an object emits a signal, all interested clients will receive a copy of the signal. There may be one client receiving it, or there may be many--or nobody may be listening. There are no replies to signals: the object emitting the signal would not know how many replies to expect, or where to expect them from.

另一种通信形式也遵循面向对象的模式。称为*信号,*这些单向通信来自一个对象,特别是无处可去。客户端进程可以注册对来自特定对象的特定名称的信号的兴趣。每当一个对象发出信号时,所有感兴趣的客户端都会收到该信号的副本。可能只有一个客户收到它,也可能有很多——或者可能没有人在听。没有对信号的回复:发出信号的对象不知道预期有多少回复,或预期来自何处。

Signals can carry parameters, just like method invocations. Of course, since signals are a strictly one-way form of communication, signals do not have input and output parameters like methods do. More recent versions of D-Bus also allow clients to restrict their interest to cases where certain of the signal's parameters match given values; they will only receive instances of the signal that match those expectations.

信号可以携带参数,就像方法调用一样。当然,由于信号是一种严格的单向通信形式,因此信号不像方法那样具有输入和输出参数。更新版本的 D-Bus 还允许客户将他们的兴趣限制在某些信号参数与给定值匹配的情况下;他们只会收到符合这些期望的信号实例。

Signals are used to publish the occurrence of events that clients may be interested in, such as the closing of some other client's connection to the bus. That particular kind of signal is sent by the object representing the bus itself. Because of this, the event can be announced properly regardless of whether the departing client closed its connection in an orderly fashion, or was killed, or crashed spectacularly.

信号用于发布客户端可能感兴趣的事件的发生,例如关闭某些其他客户端与总线的连接。这种特殊类型的信号由代表总线本身的对象发送。正因为如此,无论离开的客户端是有序关闭连接,还是被杀死,还是突然崩溃,都可以正确地宣布事件。

Interfaces(接口)

So every object supports particular methods and may emit particular signals. These are known collectively as the object's members.

所以每个对象都支持特定的方法并且可能会发出特定的信号。这些统称为对象的成员。

All of an object's members are specified in interfaces. Like their namesakes in the Java language, interfaces are sets of declarations. "Implementing" an interface is tantamount to promising to provide all methods specified in the interface, and announcing the availability of its signals for listeners. Each of these members must accept and/or provide parameters exactly as specified in the interface.

对象的所有成员都在接口中指定*。* 就像它们在 Java 语言中的同名一样,接口是一组声明。“实现”一个接口无异于承诺提供接口中指定的所有方法,并宣布其信号可供侦听器使用。这些成员中的每一个都必须完全按照接口中的规定接受和/或提供参数。

Any object may implement a given interface, just as in Java any number of classes may implement the same interface. Conversely, a single object may implement any number of interfaces. (With D-Bus it probably wouldn't make much sense to have an object that implemented no interfaces at all, though, which is perfectly normal with Java classes.) The combination of all interfaces supported by the object is called the object's type.

任何对象都可以实现给定的接口,就像在 Java 中任何数量的类都可以实现相同的接口一样。相反,单个对象可以实现任意数量的接口。(对于 D-Bus,让一个完全没有实现接口的对象可能没有多大意义,但这对于 Java 类来说是完全正常的。)对象支持的所有接口的组合称为对象的类型。

When a client invokes a method or listens for a signal, it must indicate the object and the member it is referring to. In addition to object and member, the client may also name the interface in which that member was specified. This can be necessary in some cases. If an object implements two interfaces, for example, that both specify a method named foo, then the object may have separate implementations for foo in the two interfaces. When a client tries to invoke foo on the object without specifying which interface it had in mind, there is no guarantee as to which of the two foo methods will be invoked. The D-Bus implementation may even refuse to carry the request message in the first place. Similarly, you wouldn't want to receive signals that looked like what you're listening for but are really different ones that happened to have the same name. Older versions of D-Bus also had a bug where request or signal messages could be lost if they failed to specify an interface.

当客户端调用方法或侦听信号时,它必须指明对象及其引用的成员。除了对象和成员之外,客户端还可以命名指定该成员的接口。在某些情况下,这可能是必要的。如果一个对象实现了两个接口,例如,都指定了一个名为 的方法foo,那么对于foo函数该对象可能有两个单独的实现接口。当客户端在没有指定它想要接口的情况下,试图调用对象连接foo时,将不能保证调用foo两种方法中的哪一种。D-Bus 实现甚至可能一开始就拒绝携带请求消息。同样,您不希望收到看起来像您正在收听的信号,但实际上却恰好具有相同名称的不同信号。旧版本的 D-Bus 也有一个错误,如果未能指定接口,则请求或信号消息可能会丢失。

Whether there is "overloading" of members within interfaces, i.e. whether multiple members of the same interface may have the same name, depends on the binding.

接口内是否存在成员“重载”,即同一接口的多个成员是否可能具有相同的名称,取决于绑定。

Addressing(寻址)

Let's just recap how your program gets all the way from not even being connected to a bus, to finding a method it wants to call or a signal it wants to listen for. Apart from the interface, which as we've seen can usually be omitted, each of these steps is a matter of identifying something that will be needed in the next step:

让我们回顾一下你的程序是如何从根本没有连接到总线到找到它想要调用的方法或它想要监听的信号的。除了我们所见的通常可以省略的界面之外,这些步骤中的每一步都是确定下一步需要的东西:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ywd8Z1MQ-1632486506563)(introduction.assets/image-20210918094937021.png)]

Most of these identifiers are also structured as paths themselves: parts of addresses may be; well-known bus names are; object paths are; and interface names are, too. This gets confusing sometimes, especially since related names are often chosen to look very similar--a connection org.freedesktop.Hal may provide an object /org/freedesktop/Hal/Manager that implements an interface org.freedesktop.Hal.Manager. The use of slashes in some identifiers and dots in others also takes some getting used to.

大多数这些标识符也被构造为路径本身:可能包含地址、著名的总线名称、对象路径、和接口名称。这有时会令人困惑,特别是因为相关名称通常被选择为看起来非常相似——一个连接org.freedesktop.Hal可能提供一个/org/freedesktop/Hal/Manager实现接口的对象org.freedesktop.Hal.Manager。在某些标识符中使用斜杠而在其他标识符中使用点也需要一些时间来适应。

Message Ordering(消息排序)

Requests from one connection to the same object are delivered in the same order in which they were sent. The same goes for multiple replies from one object to the same client.

从一个连接到同一个对象的请求以它们发送的相同顺序传递。从一个对象到同一个客户端的多个回复也是如此。

This does not mean that all messages are always delivered in sending order. For example, if two client processes send requests to the same object around the same time, there is no documented guarantee that the object will receive them in the same order. Even when one client sends two subsequent requests to the same object, then waits for both replies, it is possible that the reply to the second request comes in before the reply to the first request. The "object" may really be a multithreaded server process with multiple requests being handled in parallel, or it may prioritize requests internally.

这并不意味着所有消息总是按发送顺序传递。例如,如果两个客户端进程大约在同一时间向同一个对象发送请求,则没有文件保证该对象将以相同的顺序接收它们。即使当一个客户端向同一个对象发送两个后续请求,然后等待两个回复时,对第二个请求的回复也可能在对第一个请求的回复之前到达。“对象”实际上可能是一个多线程服务器进程,多个请求被并行处理,或者它可能在内部优先处理请求。

Activation(激活)

So far we've assumed that objects are created by active clients. There is another way of offering services on the bus: the bus daemon can be instructed to start (or activate) clients automatically when needed. Activation of a client can be triggered in two ways, both keyed by a well-known bus name that the activated client must obtain:

到目前为止,我们假设对象是由活动客户端创建的。还有另一种在总线上提供服务的方法:可以指示总线守护进程在需要时自动启动(或激活)客户端。客户端的激活可以通过两种方式触发,两者都由激活的客户端必须获得的众所周知的总线名称作为关键字:

	Through an explicit request to the object representing the bus itself.		By invoking a method on an object in the context of the client's well-known bus name. The latter can be inhibited through an option in the method invocation message. Some bindings may try to activate an appropriate client when you create a proxy on a well-known bus name that is not currently in use; others may defer this until you use the proxy to invoke the method. The difference can matter if you listen for a signal coming from an object: if the client that should provide the object is not actually running, you could wait in vain!
  1. 通过对代表总线本身的对象的显式请求。
  2. 通过在客户端众所周知的总线名称的上下文中调用对象上的方法。后者可以通过方法调用消息中的选项来禁止。当您在当前未使用的知名总线名称上创建代理时,某些绑定可能会尝试激活适当的客户端;其他人可能会推迟此操作,直到您使用代理来调用该方法。如果您侦听来自对象的信号,差异可能很重要:如果应该提供对象的客户端实际上没有运行,您可能会徒劳地等待!
To create a client that can be activated, describe it in a service file. A service file looks like a human-readable ".ini" file, line-based and encoded in UTF-8. Its name must always end in ".service".

要创建可激活的客户端,请在服务文件中对其进行描述*。* 服务文件看起来像人类可读的“.ini”文件,基于行并以 UTF-8 编码。它的名称必须始终以“ .service”结尾。

For example, you might want to register the fact that client program /usr/local/bin/bankcounter can be run to provide well-known bus names com.bigmoneybank.Deposits and com.bigmoneybank.Withdrawals. To do that, you'd write a service file "bankcounter.service" (the name is arbitrary, so long as it ends with .service) looking like:

例如,您可能想要注册这样一个事实,即/usr/local/bin/bankcounter可以运行客户端程序以提供众所周知的总线名称com.bigmoneybank.Depositscom.bigmoneybank.Withdrawals. 为此,您需要编写一个服务文件“ bankcounter.service”(名称是任意的,只要以.service结尾),如下所示:

# (Lines starting with hash marks are comments)# Fixed section header (do not change):[D-BUS Service]Names=com.bigmoneybank.Deposits;com.bigmoneybank.WithdrawalsExec=/usr/local/bin/bankcounter
The Names line lists the well-known connection names that the client will provide, separated by semicolons (there may also be an extra semicolon at the end). The Exec line gives the name of the program to execute in order to activate the client.

Names行列出了客户端将提供的众所周知的连接名称,以分号分隔(末尾也可能有一个额外的分号)。该Exec行给出了为了激活客户端而要执行的程序的名称。

The service files go into a directory indicated in a <servicedir> block in the bus' configuration file; the default location is /usr/share/dbus-1/services/. If you add service files while the bus is running, the bus daemon will notice and read them without any further prodding.

服务文件进入<servicedir>总线配置文件中块指示的目录;默认位置是/usr/share/dbus-1/services/。如果您在总线运行时添加服务文件,则总线守护程序会注意到并读取它们,而无需任何进一步的激活。

More detailed information about activation can be found in Raphaël Slinckx's DBus Activation Tutorial.

有关激活的更多详细信息,请参阅 Raphaël Slinckx 的 DBus激活教程

原文链接

https://www.freedesktop.org/wiki/IntroductionToDBus/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值