Method replies are generated automatically with the contents of the output parameters (if there were any) by the QtDBus implementation. Slots need not worry about constructing proper QDBusMessage objects and sending them over the connection.
Delayed Replies
In some circumstances, the called slot may not be able to process the request immediately. This is frequently the case when the request involves an I/O or networking operation which may block.
If this is the case, the slot should return control to the application's main loop to avoid freezing the user interface, and resume the process later. To accomplish this, it should make use of the extra QDBusMessage parameter at the end of the input parameter list and request a delayed reply.
We do this by writing a slot that stores the request data in a persistent structure, indicating to the caller using QDBusMessage::setDelayedReply(true) that the response will be sent later.
struct RequestData
{
QString request;
QString processedData;
QDBusMessage reply;
};
QString processRequest(const QString &request, const QDBusMessage &message)
{
RequestData *data = new RequestData;
data->request = request;
message.setDelayedReply(true);
data->reply = message.createReply();
QDBusConnection::sessionBus().send(data->reply);
appendRequest(data);
return QString();
}
The use of QDBusConnection::sessionBus().send(data->reply) is needed to explicitly inform the caller that the response will be delayed. In this case, the return value is unimportant; we return an arbitrary value to satisfy the compiler.
When the request is processed and a reply is available, it should be sent using the QDBusMessage object that was obtained. In our example, the reply code could be something as follows:
void sendReply(RequestData *data)
{
// data->processedData has been initialized with the request's reply
QDBusMessage &reply = &data->reply;
// send the reply over D-Bus:
reply << data->processedData;
QDBusConnection::sessionBus().send(reply);
// dispose of the transaction data
delete data;
}
As can be seen in the example, when a delayed reply is in place, the return value(s) from the slot will be ignored by QtDBus. They are used only to determine the slot's signature when communicating the adaptor's description to remote applications, or in case the code in the slot decides not to use a delayed reply.
The delayed reply itself is requested from QtDBus by calling QDBusMessage::reply() on the original message. It then becomes the resposibility of the called code to eventually send a reply to the caller.
Warning: When a caller places a method call and waits for a reply, it will only wait for a limited amount of time. Slots intending to take a long time to complete should make that fact clear in documentation so that callers properly set higher timeouts.
See also Using QtDBus Adaptors, Declaring Signals in D-Bus Adaptors, The QtDBus Type System, QDBusConnection, and QDBusMessage.
[Using QtDBus Adaptors]
[Next: Declaring Signals in D-Bus Adaptors]