Реплики удаленных объектов Qt
Реплики объектов
Реплика удаленного объекта — это прокси-объект, имеющий (приблизительно) такой же API, что и исходный QObject, который он дублирует. Есть несколько дополнительных свойств и сигналов, чтобы можно было определить, когда реплика инициализирована или потеряна связь с исходным объектом. Есть и другие отличия: постоянное свойство в источнике не может быть постоянным в реплике. Значение не будет известно на момент создания реплики, оно станет известным только после инициализации реплики (см. Взаимодействие с удаленными объектами).
Скомпилированная реплика — это тип, базирующийся на QRemoteObjectReplica, где определение класса-наследника автоматически генерируется компилятором repc. Генерируется только заголовочный файл (и использование макроса REPC_REPLICA в вашем файле .pro может сделать генерацию частью процесса сборки), но это — полностью готовый тип. Нет публичного конструктора, для создания экземпляра реплики необходимо использовать шаблонную функцию QRemoteObjectNode::acquire.
Реплика QRemoteObjectDynamicReplica может быть сгенерирована во время выполнения. Для этого вызывается нешаблонная версия QRemoteObjectNode::acquire(), передавая в качестве аргумента имя источника (объект QString). Динамические реплики немного сложнее в использовании с C++, но не требуют компиляции и могут быть легко использованы в QML или (возможно) в скриптовых языках, таких как Python. Динамические реплики не поддерживают начальные значения свойств и не поддерживают интроспекцию до тех пор, пока они не будут инициализированы.
Важное различие между этими двумя способами создания реплик заключается в поведении до инициализации реплики. Поскольку динамическая реплика получает metaObject только после инициализации, у неё фактически нет API до инициализации. Нет свойств и нет сигналов для подключения слотов. Из-за создания metaObject во время компиляции для скомпилированных реплик, их API доступен при создании реплики. Вы даже можете задать значения по умолчанию для свойств в файле шаблона, которые будут использоваться до тех пор, пока реплика не будет инициализирована текущими значениями из источника.
См. QRemoteObjectReplica и QRemoteObjectDynamicReplica
Инициализация реплики
Узел-хост будет обмениваться списком источников, которые он предоставляет, и всеми другими узлами, которые подключаются к нему. Он будет отправлять обновления, когда источники добавляются или удаляются из списка. Таким образом, подключенный узел всегда будет знать, к каким источникам он может подключиться. Изменения в конкретном источнике распространяются только на узлы, у которых есть реплика этого источника. Это позволяет избежать ненужного сетевого трафика.
Когда узел получает реплику для известного источника, реплика-узел отправляет запрос об этом источнике узлу-хосту. При получении этого запроса хост создаст пакет ответа с текущими значениями всех свойств источника. Если запрашиваемая реплика динамическая, он будет включать определение API для источника. Реплика-узел будет включён в список подключений, которые в дальнейшем будут получать изменения в этом источнике.
Если реплика создана, но узел не подключён к узлу, предоставляющему запрашиваемый источник (или этот объект находится в процессе узла-хоста, но совместное использование/удаленное использование не было включено для QObject), реплика всё равно будет создана, она просто останется неинициализированной.
Если впоследствии реплика-узел получит уведомление о том, что запрашиваемый источник доступен от подключённого узла, он в этот момент запросит источник и запустит процесс инициализации.
Если соединение с узлом-хостом потеряно, реплика перейдёт в недопустимое состояние. Она будет пытаться переподключиться и повторно инициализироваться, если соединение будет восстановлено (что гарантирует актуальность всех свойств).
Владение репликой
Методы acquire возвращают указатель на реплику QObject, созданную узлом. Узел не может знать предполагаемый срок жизни реплики, поэтому ответственность за удаление реплики, когда она больше не нужна, лежит на вызывающей программе.
Вы можете создать несколько копий одной и той же реплики (это может быть необходимо, например, в QML). Все реплики одного и того же источника от одного узла будут использовать частую переменную данных, которая обрабатывает сетевое взаимодействие. Это означает, что несколько экземпляров реплики не вносят дополнительного сетевого трафика, хотя будет некоторая дополнительная нагрузка на обработку. Если не удалить реплики, это предотвратит сброс счётчика ссылок на этот частный объект и вызовет ненужное сетевое взаимодействие до завершения вызывающего процесса. По этой причине рекомендуется использовать QScopedPointer или QSharedPointer для отслеживания срока жизни реплики.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-5.9/qtremoteobjects-replica.html