Intento descubrir cómo implementar múltiples MqttClients con el proyecto de GitHub MosQtitto desde Alepez.
https://github.com/alepez/MosQtitto
Un cliente se crea con la class MqttClient, pero no sé cómo usar la class MqttClientSingleton para crear varios clientes en main.qml (App.qml en el proyecto).
MqttClientSingleton.hpp
#ifndef MQTTCLIENTSINGLETON_HPP #define MQTTCLIENTSINGLETON_HPP #include "MqttClient.hpp" class MqttClientSingleton { public: static MqttClient* get(); static void set(MqttClient*); }; #endif // MQTTCLIENTSINGLETON_HPP
MqttClientSingleton.cpp
#include "MqttClientSingleton.hpp" #include <QDebug> static MqttClient* instance{nullptr}; MqttClient* MqttClientSingleton::get() { return instance; } void MqttClientSingleton::set(MqttClient* newInstance) { instance = newInstance; }
Creo que la class debe estar registrada con
qmlRegisterSingletonType
para usarlo en main.qml ¿Alguien sabe cómo registrarlo y cómo implementar múltiples clientes con él?
Soy el autor de MosQtitto. MqttClient
es la class correcta para usar cuando quiera múltiples instancias. MqttClientSingleton
existe para tener solo una instancia (y una connection de tcp) para usar tanto en qml como en c ++ al mismo time.
Solo si necesita una sola instancia, compartida entre el código qml y c ++, puede usar el singleton. Este es un extracto de un complemento qt que escribí:
void MyPlugin::initializeEngine(QQmlEngine* engine, const char* uri) { Q_UNUSED(engine); Q_UNUSED(uri); /* First, instantiate MQTT Singleton */ MqttClientSingleton::set(new MqttClient{}); engine->setObjectOwnership(MqttClientSingleton::get(), QQmlEngine::CppOwnership); } void MyPlugin::registerTypes(const char* uri) { Q_UNUSED(uri); qmlRegisterSingletonType<MqttClient>(uri, 1, 0, "MqttClientSingleton", [](QQmlEngine*, QJSEngine*) -> QObject* { return MqttClientSingleton::get(); });
Si no necesita un complemento, solo cree la instancia y registre el tipo en la function principal, como puede encontrar en el ejemplo de main.cpp
en el proyecto.
Asegúrate de llamar a mosquitto_lib_init();
antes de instanciar cualquier MqttClient y llamar a mosquitto_lib_cleanup();
cuando el progtwig finaliza, después de que todas las instancias de MqttClient hayan sido eliminadas.
Si desea registrarlo como singleton, disponible para QML, la llamada es
int qmlRegisterSingletonType<T>(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(* ) ( QQmlEngine *, QJSEngine * ) callback)
como se describe en la documentation .
Entonces para su class podría ser algo como esto:
qmlRegisterSingletonType<MqttClientSingleton>("MqttClientSingleton", 1, 0, "MqttClientSingleton", MqttClientSingleton::singletonProvider);
La última parte de esta llamada es un puntero de function a un método que tiene la firma específica:
static QObject* singletonProvider(QQmlEngine*, QJSEngine*)
Este método devolverá la instancia. Entonces puedes escribir
QObject* MqttClientSingleton::singletonProvider(QQmlEngine*, QJSEngine*) { return MqttClientSingleton::instance(); }
Pero a la segunda parte de su pregunta:
y cómo implementar múltiples clientes con él?
Debo decir que no conozco los detalles del MqttClientSingleton
, pero como es un Singleton
probablemente no sea posible. Todo el propósito de Singleton
es que puedes dar por sentado que en todo momento hay una y solo una instancia de esta class. Entonces no puedes tener múltiples instancias. Si no necesita varias instancias para varios clientes, entonces podría funcionar.
Si tiene acceso al código, puede ver, si puede refactorizarlo para deshacerse del singleton, registrarlo como tipo de QML común y ser feliz …
No olvide que el tipo de devolución del
singletonProvider
esQObject*
. Así que asegúrese de que el valor devuelto sea del tipoQObject*
. Esto significa que necesita henetworkingarQObject
y necesita usar la macroQ_OBJECT
en su class para que funcione. También necesita crearQ_PROPERTIES
para acceder a los valores yQ_INVOCABLES
para hacer que las funciones se puedanQ_INVOCABLES
desde QML