Sur cette page

Abonnement WebSockets MQTT

Combinaison d'un client MQTT et d'une connexion WebSocket.

WebSockets MQTT Subscription montre comment concevoir un QIODevice personnalisé pour combiner une connexion web socket avec QMqttClient.

Note : Depuis Qt WebSockets 6.10, les WebSockets sont supportés nativement par Qt MQTT. Cet exemple est retenu pour démontrer comment mettre en œuvre un transport personnalisé.

Création d'un QIODevice personnalisé

Le nouveau périphérique personnalisé, WebSocketIODevice, doit être une sous-classe de QIODevice:

class WebSocketIODevice : public QIODevice
{
    Q_OBJECT
public:
    WebSocketIODevice(QObject *parent = nullptr);

    bool isSequential() const override;
    qint64 bytesAvailable() const override;

    bool open(OpenMode mode) override;
    void close() override;

    qint64 readData(char *data, qint64 maxlen) override;
    qint64 writeData(const char *data, qint64 len) override;

    void setUrl(const QUrl &url);
    void setProtocol(const QByteArray &data);
Q_SIGNALS:
    void socketConnected();

public slots:
    void handleBinaryMessage(const QByteArray &msg);
    void onSocketConnected();

private:
    QByteArray m_protocol;
    QByteArray m_buffer;
    QWebSocket m_socket;
    QUrl m_url;
};

Conception d'une classe pour gérer la connexion et l'abonnement

WebSocketIODevice sera un membre privé de la classe ClientSubscription aux côtés des classes QMqttClient et QMqttSubscription:

private:
    QMqttClient m_client;
    QMqttSubscription *m_subscription;
    QUrl m_url;
    QString m_topic;
    WebSocketIODevice m_device;
    int m_version;

S'abonner et recevoir des messages

La logique principale est mise en œuvre dans la méthode connectAndSubscribe() de la classe ClientSubscription. Vous devez vérifier que le socket web s'est connecté avec succès avant de pouvoir initialiser une connexion MQTT. Une fois la connexion MQTT établie, QMqttClient peut s'abonner au sujet. Si l'abonnement est réussi, le QMqttSubscription peut être utilisé pour recevoir des messages du sujet abonné qui seront traités par la méthode handleMessage() de la classe ClientSubscription.

void ClientSubscription::connectAndSubscribe() { qCDebug(lcWebSocketMqtt)<< "Connecting to broker at "<< m_url ; m_device.setUrl(m_url) ; m_device.setProtocol(m_version == 3 ? "mqttv3.1": "mqtt") ; connect(&m_device, &WebSocketIODevice::socketConnected, this, [this]() { qCDebug(lcWebSocketMqtt)<< "WebSocket connecté, initialisation de la connexion MQTT."; m_client.setProtocolVersion(m_version == 3 ? QMqttClient::MQTT_3_1 : QMqttClient::MQTT_3_1_1) ; m_client.setTransport(&m_device, QMqttClient::IODevice) ; connect(&m_client, &QMqttClient::connected, this, [this]() { qCDebug(lcWebSocketMqtt)<< "Connexion MQTT établie"; m_subscription = m_client.subscribe(m_topic) ; if (!m_subscription) {                qDebug() << "Failed to subscribe to " << m_topic;
               emit errorOccured() ; } connect(m_subscription, &QMqttSubscription::stateChanged, [](QMqttSubscription::SubscriptionState s) { qCDebug(lcWebSocketMqtt)<< "Subscription state changed :"<< s ; }) ; connect(m_subscription, &QMqttSubscription::messageReceived, [this](QMqttMessage msg) { handleMessage(msg.payload()) ; }) ; }) ; m_client.connectToHost() ; }) ; if (!m_device.open(QIODevice::ReadWrite))        qDebug() << "Could not open socket device";
}

Fichiers :

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.