Qtブログ(日本語)

QtMqtt について

作成者: 鈴木 佑|Aug 17, 2017 1:11:08 AM

この記事は The Qt BlogIntroducing QtMqtt を翻訳したものです。
執筆: Maurice Kalinowski, 2017年8月14日

最近、オートメーション分野にむけたアプローチについての議論が活発に行われています。興味のある方は、こちら と別の ブログ記事 も合わせてご覧ください。

オートメーションむけのプロジェクトを開始するにあたって、最初の障壁は適切なコミュニケーションスタックの構築です。MQTT はテレメトリデータ(センサーからのデータの収集やデバイスの状態など)の管理で、ここ数年でとても注目を集めている技術で、今回これをサポートすることで開発のワークフローの単純化に対応することにしました。

MQTT とは

MQTT の自身の説明 を引用します。

"It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium."

(MQTT は究極的に軽量にメッセージの発行、取得ができるように設計されています。コードのフットプリントの小ささが求められるような場所やネットワークの帯域が非常に高価な場所との遠隔通信に威力を発揮します。)

パブリッシャー/サブスクライバー方式の採用により、ルーティングはすべてのクライアントが接続するサーバー側(この場合「メッセージブローカー」と呼ぶ)の担当になります。メッセージの伝搬を保証するため、複数のレベルのサービスの質の指定が可能です。

接続自体は通常は TCP 接続の上で行われますが、オーダー型でロスレスで双方向通信であればどれでも利用可能です。

QtMqtt が担う役割

QtMqtt はクライアント側の実装で、デバイスからの送信や、データの受信や管理のモニタリングのソリューションを提供します。ブローカー側は対象外です。

ここで明記したいのは、QtMqtt を仕様に完全準拠したものにしたいということで、具体的には以下の対応を意味します。

  • プロトコルレベル 3.1 および 3.1.1(バージョン 4 的に知られています)
  • すべての QoS レベル
  • ワイルドカード
  • 認証
  • SSL 接続
  • 遺言機能

では QtMqtt の実際の使い方を見てみましょう。

データの送信:


QMqttClient publisher;
publisher.setHostname(“some.brokerlocation.com”);
publisher.setPort(1883);
publisher.connectToHost();

publisher.publish(“sensor_1/dataset/foo”, “values”, qosLevel);

データの受信:

QMqttClient subscriber;
subscriber.setHostname(“some.brokerlocation.com”);
subscriber.setPort(1883);
subscriber.connectToHost();
. . .
QSharedPointer<QMqttSubscription> sub = subscriber.subscribe(“sensor_1/#”, qosLevel);
connect(sub.data(), &QMqttSubscription::messageReceived, [&](QMqttMessage msg) {
qDebug() << “New Message:” << msg.payload();
});

セキュリティ

すべての通信がセキュアで安全であることは非常に重要です。QtMqtt は2つの方法でこれを実現します:

  1. 接続確立時のユーザー名とパスワードによる認証
  2. SSL/TSL ソケットの利用

後者では、QtNetwork に含まれる QSslSocket を利用することが可能です。QMqttClient では connectToHostEncrypted() メソッドを実行することで、QSslSocket と同じように利用することができます。

QtMqtt の拡張

MQTT は TCP 上で利用されるケースがほとんどですが、それに限定されているわけではありません。QtMqtt でも他の通信方式を指定することが可能で、QIODeviceQAbstractSocket を指定することができます。これにより、独自の通信方式を実装し、接続前の QMqttClient に渡すことも可能になります。

Qt が提供している機能でいくと、MQTT を websocket 上で動かすのがいい例でしょう。QWebSocket は送受信の意味合いが異なるため、QAbstractSocket を継承してはいません。ですが、MQTT のデータを websoket 上で送出するための仕様はとても明確です(バイナリデータとして送る、一つのデータグラムに割り当てる、などなど…)。このため、その間を取り持つクラスの実装はとても簡単です。QtMqtt モジュールのサンプルの中にすでにこれを実現したものがありますので、ぜひ見てみてください。

この記事に興味がある方は、プレリリースバージョンを提供いたしますので、是非 お問い合わせ ください。