Development/Tutorials/D-Bus/Introduction (es): Difference between revisions

From KDE TechBase
No edit summary
No edit summary
(10 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:I18n/Language Navigation Bar|Development/Tutorials/D-Bus/Introduction}}
 


{{TutorialBrowser|
{{TutorialBrowser|
Line 12: Line 12:
}}
}}


== Abstracto ==
== Resumen ==


[http://www.freedesktop.org/wiki/Software/dbus '''D-Bus'''] es un software '''Libre''' y de '''Código Abierto''' especializado en el mecanismo de comunicación entre procesos '''I'''nter-'''P'''rocess '''C'''ommunication (IPC)) que es ampliamente utilizado hoy día para el software de código abierto para escritorio. Es parte del proyecto[http://freedesktop.org freedesktop.org] y se utiliza en amplio rango de aplicaciones. Ejemplos de su uso lo tenemos en las notificaciones hotplug de Linux, consultas de búsquedas de escritorio en strigi y también como medio primario de Comunicación Entre Procesos de KDE 4. Este tutorial sirve de introducción a la terminología de D-Bus y sus conceptos básicos, desde la perspectiva del programador de aplicaciones.
[http://www.freedesktop.org/wiki/Software/dbus '''D-Bus'''] es un software '''Libre''' y de '''Código Abierto''' especializado en el mecanismo de comunicación entre procesos ('''I'''nter-'''P'''rocess '''C'''ommunication (IPC)) que es ampliamente utilizado hoy día para el software de código abierto para escritorio. Es parte del proyecto [http://freedesktop.org freedesktop.org] y se utiliza en amplio rango de aplicaciones. Ejemplos de su uso lo tenemos en las notificaciones hotplug de Linux, consultas de búsquedas de escritorio en strigi y también como medio primario de Comunicación Entre Procesos de KDE 4. Este tutorial sirve de introducción a la terminología de D-Bus y sus conceptos básicos, desde la perspectiva del programador de aplicaciones.


== ¿Que es IPC? ==
== ¿Que es IPC? ==
Line 22: Line 22:
La utilización de IPC en el escritorio va desde el scripting (que permite utilizar un script (conjunto de sentencias) en un entorno común para interactuar o controlar varias aplicaciones) hasta para proveer acceso a servicios centralizados, permitiendo la coordinación entre múltiples instancias de aplicaciones cooperativas.
La utilización de IPC en el escritorio va desde el scripting (que permite utilizar un script (conjunto de sentencias) en un entorno común para interactuar o controlar varias aplicaciones) hasta para proveer acceso a servicios centralizados, permitiendo la coordinación entre múltiples instancias de aplicaciones cooperativas.


Como ejemplo concreto, el acceso a ficheros en KDE se realiza habitualmente a través del sistema de ficheros virtual (VFS:Virtual File System) KIO utilizando KIOSlaves. KIOSlaves consiste en una serie de aplicaciones que permiten el acceso a datos sobre un protocolo dado o especificación (e.g. http o APIs del sistema de ficheros local) mediante la implementación de funciones tales como  lectura (read), escritura (write), etc
Como ejemplo concreto, el acceso a ficheros en KDE se realiza habitualmente a través del sistema de ficheros virtual (VFS:Virtual File System) KIO utilizando KIOSlaves. KIOSlaves consiste en una serie de aplicaciones que permiten el acceso a datos sobre un protocolo dado o especificación (e.g. http o APIs del sistema de ficheros local) mediante la implementación de funciones tales como  lectura (read), escritura (write), etc. Los esclavos (slaves) corren como procesos independientes e intercambian datos con la aplicación — con la cual el usuario está interactuando — asíncronamente a través de IPC. Esto no solamente permite que múltiples aplicaciones utilicen el mismo esclavo (slave) sino que además permite al mismo esclavo mantenerse simple de forma que pueda realizar cosas como bloqueo de operaciones sin que ello cause el propio bloqueo de la aplicación gráfica.
Los esclavos (slaves) corren como procesos independientes e intercambian datos con la aplicación — con la cual el usuario está interactuando &mdash asíncronamente a través de IPC. Esto no solamente permite que múltiples aplicaciones utilicen el mismo esclavo (slave) sino que además permite al mismo esclavo mantenerse simple de forma que pueda realizar cosas como bloqueo de operaciones sin que ello cause el propio bloqueo de la aplicación gráfica.
La aplicación gráfica nunca ve actualmente la ocurrencia IPC, como si esta tuviese lugar detrá de las escenas de la API KIO.
La aplicación gráfica nunca ve actualmente la ocurrencia IPC, como si esta tuviese lugar detrá de las escenas de la API KIO.


Line 34: Line 33:


D-Bus aporta múltiples "buses" de mensaje para que las aplicaciones se comuniquen entre sí. Cada bus aporta sus propias facilidades de conexión, la cual permite la separación de las diferentes categorias de mensajes: los mensajes enviados por un bus no pueden ser accedidos por otro bus, pero las aplicaciones conectadas al mismo bus pueden comunicarse entre ellas a trávés de él. De esta forma múltiples aplicaciones se pueden conectar al mismo bus en cualquier momento y también una aplicación se puede conectar a múltiples buses simultaneamente. Esto permite la aplicación de diferentes políticas de seguridad a buses diferentes al tiempo que se mantiene una eficiente compartición tanto de los mensajes locales como globales.  
D-Bus aporta múltiples "buses" de mensaje para que las aplicaciones se comuniquen entre sí. Cada bus aporta sus propias facilidades de conexión, la cual permite la separación de las diferentes categorias de mensajes: los mensajes enviados por un bus no pueden ser accedidos por otro bus, pero las aplicaciones conectadas al mismo bus pueden comunicarse entre ellas a trávés de él. De esta forma múltiples aplicaciones se pueden conectar al mismo bus en cualquier momento y también una aplicación se puede conectar a múltiples buses simultaneamente. Esto permite la aplicación de diferentes políticas de seguridad a buses diferentes al tiempo que se mantiene una eficiente compartición tanto de los mensajes locales como globales.  


Se aporta por defecto un bus de sistema amplio para mensajes internos del kernel (núcleo) del sistema operativo y para otros servicios globales del sistema denominándose, apropiadamente, el '''bus del sistema''' (the '''system bus''').  
Se aporta por defecto un bus de sistema amplio para mensajes internos del kernel (núcleo) del sistema operativo y para otros servicios globales del sistema denominándose, apropiadamente, el '''bus del sistema''' (the '''system bus''').  
Line 44: Line 42:
Adicionalmente, una aplicación puede crear su propio bus privados con otra aplicación en la modalidad de igual a igual (peer to peer).
Adicionalmente, una aplicación puede crear su propio bus privados con otra aplicación en la modalidad de igual a igual (peer to peer).


No hay un límite práctico sobre el número de buses que pueden utilizar las aplicaciones asociadas a un usuario. Sin embargo es en la habilidad de compartir buses — y por tanto mensajes comunes — donde brillan realmente sistemas como D-Bus
No hay un límite práctico sobre el número de buses que pueden utilizar las aplicaciones asociadas a un usuario. Sin embargo es en la habilidad de compartir buses — y por tanto mensajes comunes — donde brillan realmente sistemas como D-Bus.


== Mensajes ==
== Mensajes ==
Line 55: Line 53:


Los mensajes pueden enviarse desde una aplicación a sí misma. Estos mensajes se cortocircuitan y por tanto se mantinen locales a la aplicación, por lo que no se hace necesario que el código de la aplicación se encargue de saber si está llamando a una aplicación local o remota. Esto es a menudo útil en aplicaciones con muchos componentes, permitiendo prevenir posibles deadlock.
Los mensajes pueden enviarse desde una aplicación a sí misma. Estos mensajes se cortocircuitan y por tanto se mantinen locales a la aplicación, por lo que no se hace necesario que el código de la aplicación se encargue de saber si está llamando a una aplicación local o remota. Esto es a menudo útil en aplicaciones con muchos componentes, permitiendo prevenir posibles deadlock.


== Espacio de nombres y direcciones ==
== Espacio de nombres y direcciones ==


Desde que múltiples aplicaciones pueden utilizar el mismo bus, y una aplicación puede tener múltiples objetos a los cuales los mensajes pueden llamar, se hace necesario establecer un medio para direccionar efectivamente y de forma inequívoca cualquier objeto en cualquier bus, similar al modo en que la dirección de una calle identifica de forma única cualquier residente u oficina. Hay tres trozos de información los cuales cuando se juntan crean una única dirección para un objeto dado en el bus: interface, servicio y nombre de objeto.
Desde que múltiples aplicaciones pueden utilizar el mismo bus, y una aplicación puede tener múltiples objetos a los cuales los mensajes pueden llamar, se hace necesario establecer un medio para direccionar efectivamente y de forma inequívoca cualquier objeto en cualquier bus, similar al modo en que la dirección de una calle identifica de forma única cualquier residente u oficina. Hay tres trozos de información los cuales cuando se juntan crean una única dirección para un objeto dado en el bus: interface, servicio y nombre de objeto.


=== Interfaces ===
=== Interfaces ===


Un '''interface''' es un conjunto de métodos y señales que pueden ser llamadas publicitándolas en el bus. An interface provides a "contract" between the applications passing messages that defines the name, parameters (if any) and return values (if any) of the interface. These methods may not map directly in a one-to-one fashion to methods or API in the application that is advertising the interface, though they often do. This allows multiple applications to provide similar or the same interfaces, regardless of internal implementation, while allowing applications to use these interfaces without worrying about the internal design of the applications.
Un '''interface''' es un conjunto de métodos y señales que pueden ser llamadas publicitándolas en el bus. Un interface establece un "contrato" entre las aplicaciones que pasan los mensajes, definiendo el nombre, parámetros (si hay alguno) y los valores de retorno (si hay alguno) del interface.  
Estos métodos pueden no corresponderse en el diseño directamente uno a uno en cuanto a métodos o API en la aplicación que está publicitando el interface, aunque ellos lo hagan así a menudo. Esto permite proveer a multiples aplicaciones  con un mismo interface o similar, a pesar de la implementación interna, mientras así permite su uso por parte de las aplicaciones sin tener que preocuparse por el diseño interno de las aplicaciones.
Los interfaces se pueden describir utilizando XML con el propósito de documentarlos y en vistas a su reutilización. La referenciación del interface mediante la descripción XML no solamente está limitada a usuarios y programadores, sino que los desarrolladores pueden utilizar clases que se autogeneran a partir de dicho XML — haciendo el uso de D-Bus mucho más fácil y menos propenso a errores (e.g. el compilador puede chequear la sintáxis de los mensajes en tiempo de compilación).


Interfaces can be described for documentation and code re-use purposes using XML. Not only can users and programmers reference the XML description of the interface, but developers can use classes that are auto-generated from the XML — making using D-Bus much easier and less error-prone (e.g. the compiler can check the syntax of messages at compile time).
=== Servicios ===


=== Services ===
Un '''servicio''' representa  una conexión de la aplicación a un bus.


A '''service''' represents an application connection to a bus.
'''Servicio''' quí corresponde a un  "bien conocido" [http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names nombres de bus] en la terminología de la especificación D-Bus. El término "nombre de Bus" es un poco confuso. A pesar de como pueda sonar, '''nombre de Bus''' son los nombres de las conexiones(!) en el bus, no los nombres de los buses(!). De ahí que deba usarse el termino '''servicio''', tal como lo llama la documentación de Qt.


'''Service''' here corresponds to "well-known" [http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names Bus names] in the D-Bus specification terminology. The term "Bus name" is a bit confusing. Regardless of how it sounds like, '''Bus names''' are the names of connections(!) on the bus, not names of buses(!). So here the term '''service''' will be used, as the Qt Documentation calls it.
Estos se mantienen únicos utilizando un acercamiento a "nombre de dominio inverso", tal como se puede ver en muchos otros sistemas que necesitan un espacio de nombres para múltiples componentes. Muchos de los servicios aportados por aplicaciones del propio proyecto KDE utilizan el prefijo <tt>org.kde</tt> para su nombre de servicio. Por lo que podemos encontrar "org.kde.screensaver" publicitado en la sesión de bus.


These are kept unique by using a "reverse domain name"  approach, as can be seen in many other systems that need to namespace for multiple components. Most services provided by applications from the KDE project itself use the <tt>org.kde</tt> prefix to their service name. So one may find "org.kde.screensaver" advertised on the session bus.
Se recomienda utilizar el nombre de dominio para una organización o de la aplicación para los nombres de servicio. Por ejemplo si tu dominio es <tt>awesomeapps.org</tt> y el nombre de tu aplicación es <tt>wickedwidget</tt> probablemente deberías utilizar <tt>org.awesomeapps.wickedwidget</tt> como el nombre del servicio en el bus.


You should use the domain name for your organization or application for your service names. For example if your domain is <tt>awesomeapps.org</tt> and the name of your application is <tt>wickedwidget</tt> you would probably use <tt>org.awesomeapps.wickedwidget</tt> as the service name on the bus.
Si una aplicación tiene más de una conexión al bus, o si se van a tener múltiples instancias de la misma aplicación funcionando al mismo tiempo, entonces se hace necesario el uso de un nombre único de servicio para cada conexión. A menudo esto se hace anexando el ID de proceso al nombre del servicio.


If an application has more than one connection to a bus, or if multiple instances of the same application may be active at once, it will need to use a unique service name for each connection. Often this is done by appending the process ID to the service name.
=== Objetos ===


=== Objects ===
Of course, an application is likely to advertise access to more than one object on the bus. This many-to-one relationship between objects and services is accommodated by providing a '''path''' component to the address. Each path associated with a service represents a different, unique object. An example might be <tt>/MainInterface</tt> or <tt>/Documents/Doc1</tt>. The actual path structure is completely arbitrary and is up to the application providing the service as to what the paths should be. Estos trayectos proveen un camino para identificar y agrupar lógicamente objetos para aplicaciones que envían mensajes a la aplicación.


Of course, an application is likely to advertise access to more than one object on the bus. This many-to-one relationship between objects and services is accommodated by providing a '''path''' component to the address. Each path associated with a service represents a different, unique object. An example might be <tt>/MainInterface</tt> or <tt>/Documents/Doc1</tt>. The actual path structure is completely arbitrary and is up to the application providing the service as to what the paths should be. These paths simply provide a way to identify and logically group objects for applications that send messages to the application.
Algunas librerias exportan trayectos a objetos con su "dominio reverso" pre-anexado al mismo, para establecer correctamente el espacio de nombres de sus objetos. Esto es bastante común para librerias y plugins que se unen a un servicio arbitrario y debe por lo tanto evitar todo choque con objetos exportados por la aplicación y otros componentes. Sin embargo, esta práctica no se utiliza en las aplicacione y librerias de KDE.


Some libraries export object paths with their "reverse domain" prepended to it, so as to properly namespace their objects. This is quite common for libraries and plugins that join an arbitrary service and must therefore avoid all clashing with objects exported by the application and other components. However, this practice is not in use in KDE applications and libraries.
Los objetos proveen acceso a interfaces. En efecto, un objeto puede proveer acceso a múltiples interfaces al mismo tiempo.


Objects provide access to interfaces. In fact, a given object can provide access to multiple interfaces at the same time.
=== Poniendo todo esto junto ===


=== Putting It All Together ===
Un mensaje de D-Bus contiene una dirección compuesta de todos los componentes citados antes, de forma que pueda ser encauzado a la aplicación correcta y las obejto y método llamado. Por lo tanto una dirección debería parecerse a la siguiente:


A D-Bus message contains an address made up of all the above components so that it can be routed to the correct application, object and method call. Such an address might look like this:
<syntaxhighlight lang="text">
 
<code>
org.kde.krunner /ScreenSaver org.kde.screensaver.setBlankOnly
org.kde.krunner /ScreenSaver org.kde.screensaver.setBlankOnly
</code>
</syntaxhighlight>


In this case <tt>org.kde.krunner</tt> is the service, <tt>/ScreenSaver</tt> is the path to the object, <tt>org.kde.screensaver</tt> is the interface the object exports and <tt>setBlankOnly</tt> is a method in the interface. If the <tt>/ScreenSaver</tt> object only provides the <tt>org.kde.screensaver</tt> interface (or the <tt>setBlankOnly</tt> method is unique amongst the services it implements) then this would work equally well as an address:
En este caso <tt>org.kde.krunner</tt> es el servicio, <tt>/ScreenSaver</tt> es la ruta al objeto, <tt>org.kde.screensaver</tt> es el interface que el objeto exporta y <tt>setBlankOnly</tt> es un método en el interface. Si el objeto <tt>/ScreenSaver</tt> solamente aporta el interface <tt>org.kde.screensaver</tt> (o el método <tt>setBlankOnly</tt> es único entre los servicios que implementa) esto debería funcionar igualmente bien como una dirección:


<code>
<syntaxhighlight lang="text">
org.kde.krunner /ScreenSaver setBlankOnly
org.kde.krunner /ScreenSaver setBlankOnly
</code>
</syntaxhighlight>
 
In this way each possible destination is uniquely and reliably addressable.


== Calling and Being Called ==
De esta forma cada destino posible es único y fiablemente direccionable.


Now that we have a way to address any given end point on the bus, we can examine the possibilities when it comes to actually sending or receiving messages.
== Llamando y siendo llamado ==


=== Methods ===
Ahora que tenemos una forma de direccionar cualquier punto final en el bus, podemos examinar las posibilidades a la hora de enviar y recibir mensajes.


Methods are messages that are sent to cause code to be executed in the receiving application. If the method is not available because, for instance, the address was wrong or the requested application is not running, an error will be returned to the calling application. If the method is successfully called, an optional return value will be returned to the calling application. Even if there is no return value provided, a success message will be returned. This round trip does have overhead, and it is important to keep this in mind for performance critical code.
=== Métodos ===


Such method calls are always initiated by the calling application and the resulting messages have exactly one source and one destination address.
Los métodos son mensajes que se envian para producir la ejecución de código en la aplicación que lo recibe. Si el método no está disponible por, supongamos que la dirección no es correcta o la aplicación no está arrancada, entonces se retorna un error a la aplicación que lo envió. En caso de que el método se llame correctamente se retornará opcionalmente un valor a la aplicación llamante. Incluso si no se aporta un valor de retorno, se enviará un mensaje indicando que todo fue correcto.  


=== Signals ===
Este viaje de información de ida y vuelta causa sobrecarga y es importante recordar esto para conseguir un buen rendimiento con el código que se escribe.
Tales llamadas a métodos son iniciadas siempre por las aplicaciones llamantes y los mensajes resultantes tienen exactamente una dirección fuente y una dirección destino.


Signals are like method calls except that they happen in the "reverse" direction and are not tied to a single destination. A signal is emitted by the application which is exporting the interface and is available to any application on the same bus. This allows an application to spontaneously advertise changes in state or other events, to any applications which may be interested in tracking those changes.
=== Señales ===


If this sounds a lot like the signal and slots mechanism in Qt, that's because it is. For all intents and purposes it is a non-local version of the same functionality.
Las señales (signals) son como las llamadas a métodos excepto por que suceden en la dirección "inversa" y no están vinculadas a un solo destino. Una señal es emitida por la aplicación que exporta el interface y está disponible para cualquier aplicación en el mismo bus. Esto permite a una aplicación advertir de cambios de estado u otros eventos, espontaneamente, a otras aplicaciones que pueden tener interés en el seguimiento de estos cambios.
Si esto suena más al mecanismo de señales y slots en QT, esto es debido a que es así. Para todos los intentos y propósitos esta es una versión no-local de la misma funcionalidad.


== Useful Tools ==
== Utilidades de interés ==


There are several useful tools for exploring the D-Bus busses as well as developing applications that use D-Bus. We will now look briefly at end-user tools as the articles that follow cover the development tools in greater detail and context.
Hay varias utilidades de interés para explorar los buses D-Bus además de para desarrollar aplicaciones que hagan uso de D-Bus. Veamos brevemente estas utilidades de usuario final ya que en los artículos que siguen se explican en más detalle y contexto.


=== qdbus ===
=== qdbus ===


<tt>qdbus</tt> is a command line tool which can be used to list the services, objects and interfaces on a given bus as well as send messages to a given address on the bus. It can be used to explore both the system and the default session bus. If the <tt>--system</tt> switch is passed, <tt>qdbus</tt> will connect to the system bus, otherwise it uses the session bus.
<tt>qdbus</tt> es una utilidad de línea de mandatos que se puede utilizar para listar servicios, objetos e interfaces de un bus determinado además de para enviar mensajes a una determinada dirección en el bus. Se puede utilizar para explorar tanto el bus del sistema como el de la sesión por defecto. Si se le pasa el switch <tt>--system</tt>, <tt>qdbus</tt> conectará con el bus del sistema, en caso contrario utilizará el bus de sesión.


<tt>qdbus</tt> uses the rest of the supplied arguments on the command as an address and, if any, parameters to pass to a given object. If a full address is not supplied, then it lists all the objects available from that point on the bus. For instance, if no addresses are provided a list of available services is listed. If a service name is provided, object paths will be provided. If a path is also provided all methods in all interfaces will be listed. In this way one can quite easily explore and interact with objects on the bus, making <tt>qdbus</tt> very useful for testing, scripting and even idle exploration.
<tt>qdbus</tt> utiliza el resto de los argumentos aportados en el mandato como una dirección y, si hay alguno más como parámetros para pasar a un objeto determinado. Si no se aporta una dirección completa, entonces lista todos los objetos disponibles para este punto en el bus. Por ejemplo, si no se aportan direcciones entonces se listan todos los servicios disponibles. Si se aporta un nombre de servicio, se proveerán trayectos a objetos. Si además se aporta un trayecto entonces se listarán todos los métodos en todos los interfaces. En este sentido uno puede explorar e interactuar facilmente con objetos en el bus, haciendo <tt>qdbus</tt> muy útil para testeos, scripting e incluso para exploración en pasivo.


=== qdbusviewer ===
=== qdbusviewer ===


<tt>qdbusviewer</tt> is a Qt application that provides a graphical interface to essentially the same set of features that <tt>qdbus</tt> provides on the command line, thus providing a more user friendly mechanism to interact with the bus. <tt>qdbusviewer</tt> ships with Qt4 itself and is easy for anyone who is familiar with the basic D-Bus concepts, such as object addresses, to use.
<tt>qdbusviewer</tt> es una aplicación Qt que aporta un interface gráfico a esenciamente las mismas características que <tt>qdbus</tt> tiene en la línea de mandatos, al tiempo que aporta un mecanismo más amigable para interactuar con el bus, <tt>qdbusviewer</tt> viene con Qt4 y es fácil de utilizar para cualquiera que esté familiarizado con los conceptos de D-Bus, tales como direcciones de objetos.

Revision as of 13:27, 18 July 2012


Introduction To D-BUS
Tutorial Series   D-Bus
Previous   None
What's Next   Accessing Interfaces
Further Reading   D-Bus documentation page

Resumen

D-Bus es un software Libre y de Código Abierto especializado en el mecanismo de comunicación entre procesos (Inter-Process Communication (IPC)) que es ampliamente utilizado hoy día para el software de código abierto para escritorio. Es parte del proyecto freedesktop.org y se utiliza en amplio rango de aplicaciones. Ejemplos de su uso lo tenemos en las notificaciones hotplug de Linux, consultas de búsquedas de escritorio en strigi y también como medio primario de Comunicación Entre Procesos de KDE 4. Este tutorial sirve de introducción a la terminología de D-Bus y sus conceptos básicos, desde la perspectiva del programador de aplicaciones.

¿Que es IPC?

El término "IPC" puede utilizarse para describir cualquier número de métodos para obtener información desde un proceso a otro. La información transmitida puede tener la forma de datos de aplicación, método de invocación o señales espontaneas. Actualmente la comunicación tiene lugar a través de sockets o pipes y algunas veces, como es el caso con D-Bus, utiliza un proceso para realizar el enrutamiento del mensaje, activación de servicio y control de acceso.

La utilización de IPC en el escritorio va desde el scripting (que permite utilizar un script (conjunto de sentencias) en un entorno común para interactuar o controlar varias aplicaciones) hasta para proveer acceso a servicios centralizados, permitiendo la coordinación entre múltiples instancias de aplicaciones cooperativas.

Como ejemplo concreto, el acceso a ficheros en KDE se realiza habitualmente a través del sistema de ficheros virtual (VFS:Virtual File System) KIO utilizando KIOSlaves. KIOSlaves consiste en una serie de aplicaciones que permiten el acceso a datos sobre un protocolo dado o especificación (e.g. http o APIs del sistema de ficheros local) mediante la implementación de funciones tales como lectura (read), escritura (write), etc. Los esclavos (slaves) corren como procesos independientes e intercambian datos con la aplicación — con la cual el usuario está interactuando — asíncronamente a través de IPC. Esto no solamente permite que múltiples aplicaciones utilicen el mismo esclavo (slave) sino que además permite al mismo esclavo mantenerse simple de forma que pueda realizar cosas como bloqueo de operaciones sin que ello cause el propio bloqueo de la aplicación gráfica. La aplicación gráfica nunca ve actualmente la ocurrencia IPC, como si esta tuviese lugar detrá de las escenas de la API KIO.

Otro ejemplo del uso de la IPC en KDE es el soporte de la aplicación única. Cuando se inicia una KUniqueApplication primeramente chequea si están corriendo otras instancias de la misma aplicación. Si es este el caso lo que hace es enviar un mensaje vía IPC para que dicha aplicación se muestre a sí misma.

El mecanismo primario de IPC para aplicaciones en KDE4 es D-BUS, el cual es un sistema muy popular utilizado por una variedad de software hoy día. QT4 aporta un conjunto de enlaces intuitivos y estables a D-Bus en la forma de clases C++. Esta serie de tutoriales introducen a D-Bus aparte de cubrir el uso de la API D-Bus en QT4. Este artículo en particular describe los conceptos de alto nivel en D-Bus y deja los detalles de como utilizar estas características y funcionalidad a los artículos que siguen.

Buses

D-Bus aporta múltiples "buses" de mensaje para que las aplicaciones se comuniquen entre sí. Cada bus aporta sus propias facilidades de conexión, la cual permite la separación de las diferentes categorias de mensajes: los mensajes enviados por un bus no pueden ser accedidos por otro bus, pero las aplicaciones conectadas al mismo bus pueden comunicarse entre ellas a trávés de él. De esta forma múltiples aplicaciones se pueden conectar al mismo bus en cualquier momento y también una aplicación se puede conectar a múltiples buses simultaneamente. Esto permite la aplicación de diferentes políticas de seguridad a buses diferentes al tiempo que se mantiene una eficiente compartición tanto de los mensajes locales como globales.

Se aporta por defecto un bus de sistema amplio para mensajes internos del kernel (núcleo) del sistema operativo y para otros servicios globales del sistema denominándose, apropiadamente, el bus del sistema (the system bus).

Este es el bus utilizado para cosas tales como señalizar cuando hay disponible nuevo hardware detectado en el sistema, tal como ocurre cuando una unidad flash se conecta o cuando se inserta un disco DVD en una unidad.

Cada sesión de escritorio (e.g. cada usuario logeado) tiene uno o más buses asociados. Estos reciben el nombre de buses de sesion. El bus por defecto de la actual sesión recibe el nombre El bus de sesión y es el que las aplicaciones de escritorio tenderán a usar con más frecuencia.

Adicionalmente, una aplicación puede crear su propio bus privados con otra aplicación en la modalidad de igual a igual (peer to peer).

No hay un límite práctico sobre el número de buses que pueden utilizar las aplicaciones asociadas a un usuario. Sin embargo es en la habilidad de compartir buses — y por tanto mensajes comunes — donde brillan realmente sistemas como D-Bus.

Mensajes

La unidad base de comunicación en un bus es el mensaje. Toda la información pasada a través de bus se realiza en forma de mensajes, similar a la información transmitida utilizando TCP/IP vía paquetes.

A diferencia de los paquetes de red, sin embargo, cada mensaje D-Bus garantiza contener el conjunto completo de datos a enviar o recibir. En adición a los datos a enviar, los mensajes además registran quienes son tanto el que envía como el destinatario para permitir el enrutamiento adecuado.

Este sistema muestra muy bien como tienden a trabajar internamente las aplicaciones de escritorio: métodos de llamada method calls (messages) result in some action being taken con la posibilidad de retornar valores. Una de las característica primarias de los mensajes con D-Bus es que son asíncronos: se puede enviar un mensaje mientras que la respuesta no ha tenido lugar por un periodo de tiempo (se generan timeouts para prevenir 'esperas por siempre' ('wait forever') deadlocks). Por supuesto, hay en la API de D-Bus en Qt4 para hacer parecer síncronas las llamadas a la aplicación llamante.

Los mensajes pueden enviarse desde una aplicación a sí misma. Estos mensajes se cortocircuitan y por tanto se mantinen locales a la aplicación, por lo que no se hace necesario que el código de la aplicación se encargue de saber si está llamando a una aplicación local o remota. Esto es a menudo útil en aplicaciones con muchos componentes, permitiendo prevenir posibles deadlock.

Espacio de nombres y direcciones

Desde que múltiples aplicaciones pueden utilizar el mismo bus, y una aplicación puede tener múltiples objetos a los cuales los mensajes pueden llamar, se hace necesario establecer un medio para direccionar efectivamente y de forma inequívoca cualquier objeto en cualquier bus, similar al modo en que la dirección de una calle identifica de forma única cualquier residente u oficina. Hay tres trozos de información los cuales cuando se juntan crean una única dirección para un objeto dado en el bus: interface, servicio y nombre de objeto.

Interfaces

Un interface es un conjunto de métodos y señales que pueden ser llamadas publicitándolas en el bus. Un interface establece un "contrato" entre las aplicaciones que pasan los mensajes, definiendo el nombre, parámetros (si hay alguno) y los valores de retorno (si hay alguno) del interface. Estos métodos pueden no corresponderse en el diseño directamente uno a uno en cuanto a métodos o API en la aplicación que está publicitando el interface, aunque ellos lo hagan así a menudo. Esto permite proveer a multiples aplicaciones con un mismo interface o similar, a pesar de la implementación interna, mientras así permite su uso por parte de las aplicaciones sin tener que preocuparse por el diseño interno de las aplicaciones.

Los interfaces se pueden describir utilizando XML con el propósito de documentarlos y en vistas a su reutilización. La referenciación del interface mediante la descripción XML no solamente está limitada a usuarios y programadores, sino que los desarrolladores pueden utilizar clases que se autogeneran a partir de dicho XML — haciendo el uso de D-Bus mucho más fácil y menos propenso a errores (e.g. el compilador puede chequear la sintáxis de los mensajes en tiempo de compilación).

Servicios

Un servicio representa una conexión de la aplicación a un bus.

Servicio quí corresponde a un "bien conocido" nombres de bus en la terminología de la especificación D-Bus. El término "nombre de Bus" es un poco confuso. A pesar de como pueda sonar, nombre de Bus son los nombres de las conexiones(!) en el bus, no los nombres de los buses(!). De ahí que deba usarse el termino servicio, tal como lo llama la documentación de Qt.

Estos se mantienen únicos utilizando un acercamiento a "nombre de dominio inverso", tal como se puede ver en muchos otros sistemas que necesitan un espacio de nombres para múltiples componentes. Muchos de los servicios aportados por aplicaciones del propio proyecto KDE utilizan el prefijo org.kde para su nombre de servicio. Por lo que podemos encontrar "org.kde.screensaver" publicitado en la sesión de bus.

Se recomienda utilizar el nombre de dominio para una organización o de la aplicación para los nombres de servicio. Por ejemplo si tu dominio es awesomeapps.org y el nombre de tu aplicación es wickedwidget probablemente deberías utilizar org.awesomeapps.wickedwidget como el nombre del servicio en el bus.

Si una aplicación tiene más de una conexión al bus, o si se van a tener múltiples instancias de la misma aplicación funcionando al mismo tiempo, entonces se hace necesario el uso de un nombre único de servicio para cada conexión. A menudo esto se hace anexando el ID de proceso al nombre del servicio.

Objetos

Of course, an application is likely to advertise access to more than one object on the bus. This many-to-one relationship between objects and services is accommodated by providing a path component to the address. Each path associated with a service represents a different, unique object. An example might be /MainInterface or /Documents/Doc1. The actual path structure is completely arbitrary and is up to the application providing the service as to what the paths should be. Estos trayectos proveen un camino para identificar y agrupar lógicamente objetos para aplicaciones que envían mensajes a la aplicación.

Algunas librerias exportan trayectos a objetos con su "dominio reverso" pre-anexado al mismo, para establecer correctamente el espacio de nombres de sus objetos. Esto es bastante común para librerias y plugins que se unen a un servicio arbitrario y debe por lo tanto evitar todo choque con objetos exportados por la aplicación y otros componentes. Sin embargo, esta práctica no se utiliza en las aplicacione y librerias de KDE.

Los objetos proveen acceso a interfaces. En efecto, un objeto puede proveer acceso a múltiples interfaces al mismo tiempo.

Poniendo todo esto junto

Un mensaje de D-Bus contiene una dirección compuesta de todos los componentes citados antes, de forma que pueda ser encauzado a la aplicación correcta y las obejto y método llamado. Por lo tanto una dirección debería parecerse a la siguiente:

org.kde.krunner /ScreenSaver org.kde.screensaver.setBlankOnly

En este caso org.kde.krunner es el servicio, /ScreenSaver es la ruta al objeto, org.kde.screensaver es el interface que el objeto exporta y setBlankOnly es un método en el interface. Si el objeto /ScreenSaver solamente aporta el interface org.kde.screensaver (o el método setBlankOnly es único entre los servicios que implementa) esto debería funcionar igualmente bien como una dirección:

org.kde.krunner /ScreenSaver setBlankOnly

De esta forma cada destino posible es único y fiablemente direccionable.

Llamando y siendo llamado

Ahora que tenemos una forma de direccionar cualquier punto final en el bus, podemos examinar las posibilidades a la hora de enviar y recibir mensajes.

Métodos

Los métodos son mensajes que se envian para producir la ejecución de código en la aplicación que lo recibe. Si el método no está disponible por, supongamos que la dirección no es correcta o la aplicación no está arrancada, entonces se retorna un error a la aplicación que lo envió. En caso de que el método se llame correctamente se retornará opcionalmente un valor a la aplicación llamante. Incluso si no se aporta un valor de retorno, se enviará un mensaje indicando que todo fue correcto.

Este viaje de información de ida y vuelta causa sobrecarga y es importante recordar esto para conseguir un buen rendimiento con el código que se escribe. Tales llamadas a métodos son iniciadas siempre por las aplicaciones llamantes y los mensajes resultantes tienen exactamente una dirección fuente y una dirección destino.

Señales

Las señales (signals) son como las llamadas a métodos excepto por que suceden en la dirección "inversa" y no están vinculadas a un solo destino. Una señal es emitida por la aplicación que exporta el interface y está disponible para cualquier aplicación en el mismo bus. Esto permite a una aplicación advertir de cambios de estado u otros eventos, espontaneamente, a otras aplicaciones que pueden tener interés en el seguimiento de estos cambios.

Si esto suena más al mecanismo de señales y slots en QT, esto es debido a que es así. Para todos los intentos y propósitos esta es una versión no-local de la misma funcionalidad.

Utilidades de interés

Hay varias utilidades de interés para explorar los buses D-Bus además de para desarrollar aplicaciones que hagan uso de D-Bus. Veamos brevemente estas utilidades de usuario final ya que en los artículos que siguen se explican en más detalle y contexto.

qdbus

qdbus es una utilidad de línea de mandatos que se puede utilizar para listar servicios, objetos e interfaces de un bus determinado además de para enviar mensajes a una determinada dirección en el bus. Se puede utilizar para explorar tanto el bus del sistema como el de la sesión por defecto. Si se le pasa el switch --system, qdbus conectará con el bus del sistema, en caso contrario utilizará el bus de sesión.

qdbus utiliza el resto de los argumentos aportados en el mandato como una dirección y, si hay alguno más como parámetros para pasar a un objeto determinado. Si no se aporta una dirección completa, entonces lista todos los objetos disponibles para este punto en el bus. Por ejemplo, si no se aportan direcciones entonces se listan todos los servicios disponibles. Si se aporta un nombre de servicio, se proveerán trayectos a objetos. Si además se aporta un trayecto entonces se listarán todos los métodos en todos los interfaces. En este sentido uno puede explorar e interactuar facilmente con objetos en el bus, haciendo qdbus muy útil para testeos, scripting e incluso para exploración en pasivo.

qdbusviewer

qdbusviewer es una aplicación Qt que aporta un interface gráfico a esenciamente las mismas características que qdbus tiene en la línea de mandatos, al tiempo que aporta un mecanismo más amigable para interactuar con el bus, qdbusviewer viene con Qt4 y es fácil de utilizar para cualquiera que esté familiarizado con los conceptos de D-Bus, tales como direcciones de objetos.