Suscripción WebSockets MQTT
Combinación de un cliente MQTT con una conexión web socket.
WebSockets MQTT Subscription muestra cómo diseñar un QIODevice personalizado para combinar una conexión de socket web con QMqttClient.
Nota: Desde Qt 6.10, los WebSockets son soportados nativamente por Qt MQTT. Este ejemplo se mantiene para demostrar cómo implementar un transporte personalizado.
Creando un QIODevice personalizado
El nuevo dispositivo personalizado, WebSocketIODevice, tiene que ser una subclase 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; };
Diseñar una clase para gestionar la conexión y la suscripción
WebSocketIODevice será un miembro privado de la clase ClientSubscription junto con el QMqttClient y el QMqttSubscription:
private: QMqttClient m_client; QMqttSubscription *m_subscription; QUrl m_url; QString m_topic; WebSocketIODevice m_device; int m_version;
Suscripción y recepción de mensajes
La lógica principal se implementa en el método connectAndSubscribe() de la clase ClientSubscription. Es necesario verificar que el socket web se ha conectado correctamente antes de poder inicializar una conexión MQTT a través de él. Una vez establecida la conexión MQTT, el QMqttClient puede suscribirse al tema. Si la suscripción tiene éxito, el QMqttSubscription se puede utilizar para recibir mensajes del tema suscrito que serán manejados por el método handleMessage() de la clase ClientSubscription.
void ClientSubscription::connectAndSubscribe() { qCDebug(lcWebSocketMqtt)<< "Conectando con broker en "<< 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 conectado, inicializando conexión 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)<< "Conexión MQTT establecida"; 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)<< "Estado de suscripción cambiado:"<< s; }); connect(m_subscription, &QMqttSubscription::messageReceived, [this](QMqttMessage msg) { handleMessage(msg.payload()); }); }); m_client.connectToHost(); }); if (!m_device.open(QIODevice::LecturaEscritura)) qDebug() << "Could not open socket device"; }
Archivos:
© 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.