Check out the new USENIX Web site. next up previous
Next: XMLGUI Up: Application Integration Technologies Previous: KParts


Desktop Communication Protocol (DCOP)

The Desktop Communication Protocol (DCOP) is the well-known KDE inter-process communication mechanism. It is based on a central server relaying function calls between applications. DCOP makes use of the Qt object serialization implementation and uses the Inter Client Exchange (ICE) protocol [12] (part of X11R6) as transport layer.

The key feature of DCOP that makes it a viable choice for Kontact's inter-component communication is that it is also able to make in-process calls and thus minimizes the overhead for communication inside the one-process Kontact component assembly.

As this is done completely transparently to the sender and receiver of DCOP calls, it makes it possible to either run Kontact components inside of the Kontact framework or as stand-alone applications without any difference to the user other than the additional GUI integration inside the Kontact framework and the features this inherently adds, e.g the integrated configuration, the summary view or the extended drag and drop support. This gives users the choice to run the application in a way that best fits to their personal working style.

DCOP Implementation

DCOP communication between processes is mediated by a special server process. This server is started with each desktop session and handles all DCOP communication between applications belonging to this session. When an application wants to talk to another application it sends the request to the DCOP server which in turn forwards the request to its destination. Responses are sent back to the server which returns them to the application from which the request originated. The fact that communication goes through a server is completely transparent to the applications using DCOP.

When an application provides a DCOP interface for use by other processes it registers itself with the application name with the DCOP server. In addition it registers each DCOP interface it provides with a specific name with the server. DCOP provides inspection functions so that it is possible to browse DCOP interfaces in order to find out which interfaces are registered and which functions they provide.

Direct function calls are not the only way to use DCOP. it is also possible to use a signaling mechanism where an application registers for a specific signal and the server then notifies the application when the signal is emitted by the application which was requested. By using wild card matching flexible control over which signals an application listens to is possible.

Actual communication in DCOP is done using the ICE library, part of the X server, as transport layer. The communication is done by using Unix sockets. DCOP intentionally doesn't provide network transparent communication because this isn't required in normal desktop scenarios and would add an additional level of complexity as well as imposing a new class of security problems which don't need to be handled if network access is disabled.

Serialization and deserialization of data is done by using the C++ stream operators associated with all the basic data types in the Qt toolkit. They use a compact binary format. This is hidden from the DCOP user. Only if new or custom datatypes are to be sent over DCOP do new stream operators have to be implemented. This is mostly very easy because it can be based on existing operators for the data types the new type is composed of.

DCOP interface compiler

For convenient instrumentation of an application with DCOP interfaces there is a special tool, the dcopidl compiler. It takes a file describing the interface and generates the C++ code required to implement the interface. The interface description file is basically a C++ class header with some additional keywords to identify the functions for instrumentation by DCOP. So usually it is enough to add these keywords to the already existing header declaring the functions to be available via DCOP and run the dcopidl compiler on this file. For normal compilation the special keywords are defined to be empty so that they are ignored by the compiler. Figure 2 shows an example of a header used to generate a DCOP interface.

Figure 2: Example code providing a DCOP interface
\begin{verbatim}class KCalendarIface : public DCOP...
...e ) = 0;
virtual void goDate( QString date ) = 0;

The dcopidl compiler also provides the capability to generate stub classes which can be used to make DCOP function calls. This way the DCOP call appears as normal type-safe function call to the calling application and the DCOP communication and the fact that the call actually is a remote function call becomes completely transparent to the applications using DCOP.

The KDE build system automates running the dcopidl compiler so that DCOP interfaces can be added or used by adding only a few lines to the Makefile templates or header files.

The abstraction introduced by the dcopidl compiler could be used to replace DCOP by another transport mechanism without any changes to applications simply by modifying the dcopidl compiler to generate stubs and interface implementations for another transport mechanism. This would be one way to add support for other inter-process communication mechanisms like D-BUS [13] or platform-specific technologies.

Application scripting

DCOP is not limited to communication between applications. It can also be used by end users to control an application remotely. There are several different methods available to do this conveniently. For example, one can use the dcop command line tool for sending DCOP requests, the corresponding GUI tool kdcop, or use the language bindings to script the application in languages like Perl or Python.

Use of DCOP in Kontact

For Kontact DCOP is the main communication mechanism between components. It is used for inter-application communication which, depending on the configuration of Kontact plugins, means interacting with applications running as external processes with their own user interface or running embedded into Kontact in-process. DCOP handles in-process calls in a special way without using the dcop server process in order to optimize the efficiency of DCOP calls.

To maximize flexibility most of the interfaces used for communication between components are not tightly coupled to the implementation of the component. There are abstract interfaces for services like "email client" or "organizer" which are implemented by specific applications like KMail or KOrganizer. In principle these services could also be implemented by other applications, so that the user could choose the specific application for being used in Kontact. This might even be used to integrate non-KDE applications by adding a small DCOP wrapper around the specific interfaces of the application to be integrated.

As components are loaded on demand and stand-alone applications might not yet have been started when another component requests communication there is a special service for starting DCOP services on demand. The component is then started according to the users configuration inside Kontact or as stand-alone process when a request to the service interface implemented by the component is initiated.

One problem that arises with components being optionally able to run stand-alone or embedded into the Kontact framework application is that the name of the application registering the DCOP interfaces is different for these two cases. Thus components inside of Kontact register twice, once with the name of the container application and a second time with the name of the stand-alone application, so that the interfaces are always available under the same name.

Unique Applications

DCOP is also used for realizing so-called "unique applications". These are applications which can only be started once per session. This is for example used to make sure that processing of mail folders, calendar or address book data always takes place in a single process in order to avoid problems with concurrent access to the same data by different instances of an application. A unique application has a simple standard DCOP interface. When a unique application is started it first looks if a process already has registered this standard DCOP interface under the name of the application. If the process already exists it is called to handle the request to start another instance. This usually means that an existing main window is activated or that command line options are processed. If the process doesn't exist yet application startup proceeds and registers the DCOP interface, so that it is visible for subsequent starting of application instances.

The standard unique application handling isn't completely sufficient for the case of Kontact, because an application can be run in two ways, as stand-alone application where the standard unique application handling applies and as embedded component where the process providing the unique DCOP interface is different from the stand-alone case. A DCOP watcher class handles this situation by forwarding the unique application DCOP requests to the correct destination. This makes sure that for example when calling KOrganizer from the command line and a KOrganizer component in Kontact is already running the component in Kontact is activated instead of running a second instance stand-alone.

Hidden DCOP functions

Kontact also makes use of a special feature of the dcopidl compiler which allows developers to hide DCOP functions from the standard interface inspection provided by the dcop and kdcop tools. This makes it possible to hide parts of the DCOP interfaces, so that they can be used for inter-component communication, but are not available to tools like dcop and kdcop which rely on the interface inspection capabilities of DCOP.

next up previous
Next: XMLGUI Up: Application Integration Technologies Previous: KParts
Cornelius Schumacher 2004-04-06