対象読者
IoTに興味があり、JavaScriptの基本的な知識がある方を対象とします。
はじめに
本連載の第2回では、ブラウザからポーリングして気候センサーのデータを取得、表示していました。しかしその方法では複数のセンサーを使用する場合やリアルタイムの処理には不向きです。そこで今回は、このようなデータ送受信に適したプロトコルであるMQTTを使って、データをリアルタイムにグラフ表示してみます。
MQTTとは
MQTTは、M2M(Machine-to-Machine)やIoTのデータ送受信に適したシンプルなプロトコルで、1999年にIBMとEurotech社により考案されました。その後、2011年にコードが公開され、2013年にはOASISという国際標準化団体で標準化が行われるようになりました。執筆時点での最新の仕様はMQTT3.1.1です。
MQTTについては多くの機能があるので、詳細は他の記事などを参照してください。本記事ではかんたんに概要を説明する程度にします。
特徴
MQTTの主な特徴として次の3つを挙げてみました。
- コネクションを維持した双方向通信
- 1対多の通信が可能(Publish/Subscribeメッセージングモデル)
- ヘッダーが最小2バイトと小さく軽量
1.コネクションを維持した双方向通信
MQTTはHTTPのようにメッセージ単位で接続が切断されず、一度サーバーに接続するとコネクションを維持します。そのため、ほぼリアルタイムにメッセージのやりとりが行うことができ、コネクションの切断によってセンサーなどの故障を検知することが可能です。
2.1対多の通信が可能
MQTTはPublish/Subscribeメッセージングモデルに基づいており、非同期に1対多のメッセージ配信ができます。Publish/Subscribeメッセージングモデルは、非同期メッセージをやりとりするためのモデルのひとつで、メッセージの送信者が特定の受信者を想定せずにメッセージを送ることができます。
PublisherはMQTTサーバーにメッセージを送信するクライアントで、Subscriberは、そのメッセージを受信するクライアントです。MQTTサーバー(MQTT3.1までは、サーバーではなくブローカーと呼ばれていた)は、Publisherから送信されたメッセージを、適切なSubscriberに配信します。
メッセージはtopicと呼ばれる名称でタグ付けされています。このtopicによってメッセージが区別されるので、Subscriberは特定のtopicのみの受信を行うことが可能です。
3.ヘッダーが最小2バイトと小さく軽量
MQTTはデータのヘッダーが最小2バイトでプロトコルもシンプルです。そのため、HTTPよりも処理速度やネットワーク帯域の点で勝っています。
MQTTサーバー
Amazonの「AWS IoT Message Broker」を始めとして、無料/有料のMQTTサーバー(ブローカー)サービスが利用できます。もちろん、このようなサービスを利用するのもいいのですが、今回は自前のサーバー(CentOS)に、オープンソースのMQTTサーバーをインストールして使ってみます。
EMQ
今ではオープンソースのMQTTサーバーも選択肢が増えてきました。今回は手軽にインストールできるうえ、MQTT仕様をフルに実装しているEMQを利用します。
インストールは公式ページのファイルをダウンロードして展開するだけです。ここでは/usr/local/以下にインストールしています。
# wget http://emqtt.io/downloads/stable/centos -O emqttd.zip # unzip emqttd.zip -d /usr/local/
起動もかんたんです。
# /usr/local/emqttd/bin/emqttd start
これでデーモンとして起動します。パラメータにstopと指定すれば終了で、consoleと指定すればコンソールモード(フォアグランド)での起動となります。
なお、以下のポートを使用するので、ファイアウォールなどで制限している場合は外部からアクセスできるように設定する必要があります。
プロトコル・用途 | ポート |
---|---|
mqtt | 1883 |
mqtts | 8883 |
http(WebSocket) | 8083 |
http(管理UI) | 18083 |
各種設定を変更するにはemqttd/etc/にある設定ファイルを編集します。ただ、今回の用途ぐらいであればデフォルトのままで十分です。
MQTTクライアント
node.jsでMQTTサーバーに接続するにはmqttというnpmモジュールを利用します。
サンプルプロジェクトの作成
t2 initコマンドでプロジェクトを作成した後、npmモジュールをインストールします。
> npm install mqtt
次はindex.jsを書き換えてみましょう。MQTTサーバーに接続してメッセージを送受信するサンプルです。
なお、Tessel 2のNode.jsはECMAScript2015(ES2015)仕様にある程度対応したバージョンです。ES2015になり、わかりやすい書き方が可能となったので、今回のサンプルはES2015の新しい記法としています。
// MQTTサーバーへ接続する(1) const client = require('mqtt').connect('mqtt://xx.xx.xx.xx'); // メッセージを受信したとき(4) client.on('message', (topic, message) => { console.log(topic + ' : ' + message); client.end(); }); // サーバーに接続したとき client.on('connect', () => { console.log('Connected to MQTT server'); const topic = 'hello'; // topicを指定する(2) client.subscribe(topic); // 3秒後にpublishする(3) setTimeout( ()=> { client.publish(topic, 'Hello MQTT'); }, 3000); });
まずは先ほど構築したMQTTサーバーを指定して接続します(1)。そして、subscribeメソッドで受信するメッセージのtopicを設定します(2)。その後publishして(3)、そのメッセージを受信して表示します(4)。
t2 run index.jsで実行すると、次のように表示されるはずです。
Connected to MQTT server hello : Hello MQTT
今回の環境ではサーバーにconnectした直後だと、うまくpublishできなかったので3秒後としています。