Qt MQTT 를 사용해보기 위해 우분투 데스크탑에 빌드환경을 구축하고 예제를 실행해본다. Qt MQTT는 커머셜 라이센스 및 GPL 로 사용할 수 있으며 커머셜 라이센스를 보유하고 있다면 MaintenanceTool 을 통해 간단하게 설치할 수 있다.
여기서는 오픈소스 라이센스하에서 사용할 것이므로 직접 소스코드를 빌드하여 빌드환경을 구축한다. 기본적으로 Qt가 설치되어 있어야하며 여기서는 이 과정 (Qt 설치)을 생략한다.
Qt MQTT 구축
다음은 git저장소를 클론하고 빌드하는 과정을 보여준다.
$ git clone https://code.qt.io/qt/qtmqtt.git
$ cd qtmqtt
$ git checkout 5.12.9
$ ~/Qt/5.12.5/gcc_64/bin/qmake
$ make
$ make install
이제 프로젝트 파일(.pro)에 다음 줄을 추가하면 mqtt 모듈을 사용할 수 있다.
QT += mqtt
클래스를 사용하기 위해 관련 (클라이언트)헤더를 포함한다.
#include <QtMqtt/QMqttClient>
#include <QtMqtt/QMqttMessage>
#include <QtMqtt/QMqttSubscription>
클라이언트 객체 생성과 호스트 연결
QMqttClient *client = new QMqttClient();
client->setHostname("Host Name");
client->setPort(1883);
클라이언트 객체는 다음과 같은 유용한 시그널을 제공한다.
QMqttClient::stateChanged
QMqttClient::disconnected
QMqttClient::messageReceived
QMqttClient::pingResponseReceived
호스트에 연결
if(client->state() == QMqttClient::Disconnected)
client->connectToHost();
토픽 구독
int qos = 0;
QMqttSubscription *subscription = client->subscribe(QMqttTopicFilter("topic"), qos);
구독이 성공하면 다음 시그널에 연결하여 메세지를 수신할 수 있다.
QMqttSubscription::messageReceived
QMqttSubscription::stateChanged
QMqttSubscription::qosChanged
구독을 취소하려면 다음과 같이 할 수 있다.
subscription->unsubscribe();
토픽의 메세지를 게시하면 해당 토픽을 구독하는 클라이언트에게 메세지를 전달한다.
client->publish(QMqttTopicName("topic"), "message");
pub/sub 예제
이제 간단한 pus/sub예제를 실행 해본다.
브로커는 라즈베리파이4에 mosquitto 를 설치하여 구축한다. 다음의 명령줄로 간단하게 설치할 수 있다.
pi@raspberrypi:~ $ sudo apt install mosquitto
다음은 우분투 데스크탑에서 실행되는 간단한 클라이언트 예제를 보여준다.
#include <QCoreApplication>
#include <QtMqtt/QMqttClient>
#include <QtMqtt/QMqttMessage>
#include <QtMqtt/QMqttSubscription>
#include <QDebug>
void subscribe(QMqttClient *client){
QString topic("sensors/house/temperature");
int qos = 0;
QMqttSubscription *subscription = client->subscribe(QMqttTopicFilter(topic), qos);
QObject::connect(subscription, &QMqttSubscription::messageReceived, [subscription](const QMqttMessage &msg){
qDebug() << "topic: " << msg.topic().name() << ", temperature: " << msg.payload().toInt() << "°C";
subscription->unsubscribe();
qApp->exit();
});
// publish message
client->publish(topic, "15");
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QMqttClient client;
client.setHostname("10.10.10.102"); // Raspberry pi4 IP Address.
client.setPort(1883);
QObject::connect(&client, &QMqttClient::stateChanged, [&client](){
if(client.state() == QMqttClient::Connected){
qDebug() << "Client Connected.";
subscribe(&client);
}
});
if(client.state() == QMqttClient::Disconnected){
// connect to broker
client.connectToHost();
}
return a.exec();
}
실행결과:
