Объявление слотов в адаптерах D-Bus
Слоты в адаптерах D-Bus объявляются так же, как обычные публичные слоты, но их параметры должны соответствовать определенным правилам (см. Систему типов Qt D-Bus для получения дополнительной информации). Слоты, параметры которых не соответствуют этим правилам или которые не являются публичными, не будут доступны через D-Bus.
Слоты могут иметь один параметр типа const QDBusMessage &, который должен стоять в конце списка входных параметров, перед любыми выходными параметрами. Этот параметр, если он присутствует, будет инициализирован копией текущего обрабатываемого сообщения, что позволяет вызываемой функции получить информацию о вызывающей функции, например, её имя соединения.
Слоты могут быть трёх типов:
- Асинхронные
- Только входные
- Входные и выходные
Асинхронные слоты
Асинхронные слоты — это слоты, которые обычно не возвращают никакого ответа вызывающей стороне. По этой причине они не могут принимать выходные параметры. В большинстве случаев, к моменту выполнения первой строки слота, вызывающая функция уже возобновила работу.
Однако, слоты не должны полагаться на это поведение. Вопросы планирования и обработки сообщений могут изменить порядок выполнения слота. Код, предназначенный для синхронизации с вызывающей стороной, должен предоставить собственный механизм синхронизации.
Асинхронные слоты отмечаются ключевым словом Q_NOREPLY в сигнатуре метода, перед типом возврата void и именем слота. Слоты quit() в примере D-Bus Complex Ping Pong — пример этого.
Слоты только для ввода
Слоты только для ввода — это обычные слоты, которые принимают параметры, передаваемые по значению или по константной ссылке. Однако, в отличие от асинхронных слотов, вызывающая сторона обычно ожидает завершения работы вызываемой стороны перед возобновлением работы. Поэтому неасинхронные слоты не должны блокировать или должны указывать в своей документации, что могут делать это.
Слоты только для ввода не имеют специальных пометок в своей сигнатуре, за исключением того, что они принимают только параметры, передаваемые по значению или по константной ссылке. Дополнительно, слоты могут принимать параметр QDBusMessage в качестве последнего параметра, который может использоваться для дополнительного анализа сообщения вызова метода.
Слоты для ввода и вывода
Как и слоты только для ввода, слоты для ввода и вывода — это те, для которых вызывающая сторона ожидает ответ. Однако, в отличие от слотов только для ввода, этот ответ будет содержать данные. Слоты, которые выводят данные, могут содержать неконстантные ссылки и могут возвращать значение. Однако, все выходные параметры должны находиться в конце списка аргументов и не должны чередоваться с входными аргументами. Дополнительно, аргумент QDBusMessage может появляться между входными и выходными аргументами.
Автоматические ответы
Ответы метода генерируются автоматически с содержимым выходных параметров (если они были) реализацией Qt D-Bus. Слотам не нужно беспокоиться о построении правильных объектов QDBusMessage и отправке их по соединению.
Однако, такая возможность остается. Если слот обнаружит, что ему необходимо отправить специальный ответ или даже ошибку, он может сделать это, используя QDBusMessage::createReply() или QDBusMessage::createErrorReply() для параметра QDBusMessage и отправить его с помощью QDBusConnection::send(). Реализация Qt D-Bus не сгенерирует никакого ответа, если слот это сделал.
Предупреждение: Когда вызывающая сторона выполняет вызов метода и ожидает ответа, она будет ожидать только ограниченное время. Слоты, предполагающие длительное время выполнения, должны ясно указывать этот факт в документации, чтобы вызывающие стороны правильно устанавливали более высокие таймауты.
Отложенные ответы
В некоторых случаях вызываемый слот может не иметь возможности обработать запрос немедленно. Это часто случается, когда запрос включает операцию ввода-вывода или сетевую операцию, которая может заблокироваться.
В этом случае слот должен вернуть управление в основной цикл приложения, чтобы избежать зависания пользовательского интерфейса, и возобновить процесс позже. Для этого он должен использовать дополнительный QDBusMessage параметр в конце списка входных параметров и запросить отложенный ответ.
Мы делаем это, написав слот, который сохраняет данные запроса в постоянной структуре, указывая вызывающей стороне с помощью QDBusMessage::setDelayedReply(true), что ответ будет отправлен позже.
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();
appendRequest(data);
return QString();
}В этом случае значение возврата не имеет значения; мы возвращаем произвольное значение для удовлетворения компилятора.
Когда запрос обработан и ответ доступен, его следует отправить, используя объект QDBusMessage, который был получен. В нашем примере код ответа может быть следующим:
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;
}Как видно из примера, когда используется отложенный ответ, возвращаемое(ые) значение(я) из слота будут проигнорированы Qt D-Bus. Они используются только для определения сигнатуры слота при передаче описания адаптера удалённым приложениям или в случае, если код в слоте решит не использовать отложенный ответ.
Сам отложенный ответ запрашивается у Qt D-Bus, вызывая QDBusMessage::reply() на исходном сообщении. Затем ответственность за отправку ответа вызывающей стороне ложится на код, который выполняется.
Предупреждение: Когда вызывающая сторона выполняет вызов метода и ожидает ответа, она будет ожидать только ограниченное время. Слоты, предполагающие длительное время выполнения, должны ясно указывать этот факт в документации, чтобы вызывающие стороны правильно устанавливали более высокие таймауты.
См. также Использование адаптеров Qt D-Bus, Объявление сигналов в адаптерах D-Bus, Система типов Qt D-Bus, QDBusConnection и QDBusMessage.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.1/qdbusdeclaringslots.html