Service Framework API

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Qt Mobility 1.1 Features

Qt Mobility 1.2.0 release is available now.

Service Framework

The Service Framework out of process API simplifies IPC. It allows applications to listen to signals, call slots, access properties, and invoke methods in QObjects in other processes.

Key Features

  • Simplifies IPC
  • Service Discovery
  • QMetaObject system based
  • Cross platform, and optimized for each platform. Linux uses dBus, Symbian uses CServer2. Fall back operation to QLocalSocket.
  • Can access Shared or Unique remote objects. Shared object are shared between all clients. Unique objects are unique to that session and client.

Detailed Description

One feature of the QMetaObject is local communication with signals and slots. Service Framework out of process communication extends this to signals or slots in other processes. The signal is intercepted, serialized and passed to the remote process where it is recreated and behaves as it were a local signal. This simplifies IPC since both the client and server can use QObject::connect and emit which are known to all Qt programmers.

Along with signals and slots the MetaObject system provides properties, method calls through slots or Q_INVOKABLE, and run time type identification. Invoked functions will serialize the request, call the remote property and return the results seamlessly to the local process. Client code to connect a remote service is:

// Create a service manager
QServiceManager manager;

// Get the interface descriptor
QList<QServiceInterfaceDescriptor> ld = manager.findInterfaces("Service");

// Get a local object
QObject '''obj = manager.loadInterface(ld[0]);

// Connect to a sample signal
connect(obj, SIGNAL (HelloWorld(QString)), this, SLOT (Hello(QString)));

With 4 lines of code IPC has been established to a remote service. The first line creates a QServiceManager which manages service discovery. The second line fetches the interface for our test object, and the third line create a new QObject for the remote service. The last line connects the remote objects HelloWorld signal to the local Hello slot. Every time the remote object emits the signal Hello will be called. The QString argument will be passed in with a copy of the remote data.

Once the QObject is created it can be treated like any other local QObject with respect to the meta object system. There is one important difference, remote services can fail. A special signal is added to QObjects, errorUnrecoverableIPCFault(QService::UnrecoverableIPCError) which is emitted if there has been a communications fault. The object should then be destroyed.

The service side requires two parts, an XML file describing the service and registration with the service. An example XML file is:

<?xml version="1.0" encoding="UTF-8"?>
<service>
 <name>IPCExampleService</name>
 <filepath>localsocket:qt_sfw_example</filepath>
 <description>Example XML file</description>
 <interface>
 <name>com.nokia.qt.example</name>
 <version>1.0</version>
 <description>Descriptive text</description>
 <capabilities></capabilities>
 </interface>
</service>


While the XML is fairly self explanatory, the filepath is important. It must start with "localsocket" which describes an out of process service. To register with the service manager:

QServiceManager manager;
const QString path = QCoreApplication::applicationDirPath() + "/xmldata/exampleservice.xml";
m.add(path);
QRemoteServiceClassRegister::registerType<SharedService>(QRemoteServiceClassRegister::SharedInstance);
QRemoteServiceControl''' control = new QRemoteServiceControl();
control->publishServices("qt_sfw_example");
#ifdef Q_OS_SYMBIAN
 RProcess::Rendezvous(KErrNone); // will be removed after tech preview
#endif
app.exec()

The first 3 lines register the XML with the service manager. They only need to be called one time to register the service. This can be done during installation for example. The next 3 lines register the object to be exported. In this case the QObject is SharedService, and is a shared instance meaning only one instance will exist for all clients. The Q_OS_SYMBIAN ifdef is required temporarily for startup with the tech preview, and can removed in future versions. After registration QCoreApplication::exec() is called to start doing work.

SharedService could be defined as:

class SharedService : public QObject
{
 Q_OBJECT
 Q_SERVICE(SharedService, "IPCExampleService", "com.nokia.qt.example", "1.0")

public:
 SharedService(QObject* parent = 0)
 : QObject(parent)
 {

}

Q_INVOKABLE QString doSomething(int input)
 {
 // do something
 }

Q_SIGNALS:
 void HelloWorld(QString string);
};

That's all there is to it!

Complete Examples

A complete example with error checking is available in the Qt Mobility examples: Echo Client which provides both a service and example UI that demonstrates Service Framework out of process communications.