2017-09-15 99 views
1

我试图弄清楚如何使用Alepez的GitHub Project MosQtitto实现多个MqttClient。如何使用GitHub项目中的MqttClientSingletonClass项目MosQtitto?

https://github.com/alepez/MosQtitto

一台客户机与MqttClient类创建的,但我不知道如何使用MqttClientSingleton类中main.qml创建多个客户端(App.qml的项目)。

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; 
    } 

我觉得班里有与

qmlRegisterSingletonType注册

在main.qml中使用它。有人知道如何注册它以及如何使用它来实现多个客户端?

回答

1

我是MosQtitto的作者。当你需要多个实例时,MqttClient是正确的类。 MqttClientSingleton存在只有一个实例(和一个tcp连接)同时在qml和C++中使用。

只有当您需要一个在qml和C++代码之间共享的实例时,才可以使用单例。这是一个Qt插件,我写的摘录:

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(); 
    }); 

如果你不需要的插件,只需要创建一个实例,并在主函数注册类型,你可以在main.cpp例如发现项目。

确保您实例化任何MqttClient之前调用mosquitto_lib_init();和呼叫mosquitto_lib_cleanup();程序结束时,所有MqttClient情况下已被删除后。

+0

谢谢你的回答! – JohnnyWaker

+0

Apperently我错了有关使用MqttClientSingleton。我试图使用它的原因是因为在main.qml中使用MqttClient两次时出现“连接错误”。 我的MqttClient实例具有不同的ID,但不知何故它们会相互干扰。你对我有一个最小的例子,main.qml中的两个实例是怎么样的? 添加第二个客户端实例时,是否需要在main.cpp中更改某些内容? – JohnnyWaker

+0

我已经更新了我的项目。现在这个例子使用两个MqttClient实例,它们工作正常。 –

0

如果你想将其注册为单身,可用于QML呼叫

int qmlRegisterSingletonType<T>(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*) (QQmlEngine *, QJSEngine *) callback) 

documentation描述。

因此,对于你的类可能是这样的:

qmlRegisterSingletonType<MqttClientSingleton>("MqttClientSingleton", 1, 0, "MqttClientSingleton", MqttClientSingleton::singletonProvider); 

此调用的最后部分是一个函数指针,指向具有特定签名的方法:

static QObject* singletonProvider(QQmlEngine*, QJSEngine*) 

这种方法应该返回实例。所以,你可以写

QObject* MqttClientSingleton::singletonProvider(QQmlEngine*, QJSEngine*) 
{ 
    return MqttClientSingleton::instance(); 
} 

但你的问题的第二部分:

以及如何使用它实现多个客户端?

我需要说 - 我不知道MqttClientSingleton的细节,但因为它是一个Singleton这很可能是不可能的。 Singleton的全部目的是,你可以理所当然地认为在任何时候都只有一个这个类的实例。所以你不能有多个实例。如果你不需要多个客户端的多个实例 - 那么它可能会工作。

如果你有机会获得代码,你可能会看到,如果你可以重构它摆脱单身的,其注册为普通QML类型和快乐......

不要忘记singletonProvider的返回类型是QObject*。所以请确保返回的值是QObject*。这意味着您需要继承QObject,并且您需要在课堂中使用Q_OBJECT宏才能使其工作。您还需要创建Q_PROPERTIES以访问值,并使Q_INVOCABLES使功能可从QML调用