MQTTってどんなもの?

2018/01/23

IT/IoT

MQTT 記事全体のイメージ

こんにちは、さきです!

LoRaWANデバイスを利用する上で必ず出てくる「MQTT」という言葉…。
もう何がなんだかさっぱり!な状態だったのですが、なんとか、自分なりに理解できたかな?という感じです!

あとで自分で読み返すためのメモも兼ねて、MQTTについてまとめてみました!

QoSについての記事も書きました!(1/25追記)

「」のアイキャッチ画像

QoSとは?MQTTにおける通信の種類!

MQTTのQoSとは?なるべくわかりやすく、を意識してまとめてみました!MQTTでPublish、もしくはSubscribeする時、Topicの他にQoSも指定する必要があります。MQTTのQoSは、「通信の品質」のことを指しています。QoSには0、1、2の3段階のレベルがあり、それぞれ異なる動作をします。

さきブログのアイコンsakiot.com
更新日:2018-01-26

Message Queue Telemetry Transport

MQTT(Message Queue Telemetry Transport)は、通信プロトコルの一種です。Webページを見るならHTTP、ファイル転送するならFTP、といったように、目的に応じていくつかの通信プロトコルがあります。

MQTTは、簡単に言うと、非同期で軽量のメッセージをやり取りするためのプロトコルです。

私は最初、「メールじゃダメなの?」って思いました。「メッセージ」という単語から、どうしても「メール的な何か」を連想しちゃうんですよね。でも、調べていくうちにメールとは全然別物だということがわかりました!

MQTTの仕組みについて触れる前に、3つの重要な用語が出てきますので、まずはそれらを順に見ていきましょう。

Publisher

まずはPublisher(パブリッシャー)!メッセージを送信する側のことです。「メッセージを送信する人」のことじゃなくて、「メッセージを送信する処理を行なうプログラム」等のことを指します。ちなみに、PublisherをGoogle翻訳にかけると、「出版社」になります。
Publisher

「PublisherがPublish(パブリッシュ)する」なんて言ったりします。PublishはGoogle翻訳で「出版します」なので、「出版社が出版します」みたいな感じですね。

Subscriber

次に、Subscriber(サブスクライバー)!メッセージを受信する側のことです。これも、「メッセージを読む人」とかじゃなくて、「メッセージを受信するプログラム」等のことを言ってます。
Subscriber

Google翻訳だと、Subscriberは「加入者」で、Subscribeが「申し込む」です。「SubscriberがSubscribeする」は、「加入者が申し込む」みたいな感じになりますね。

Broker

最後に、Broker(ブローカー)です!Publisherからメッセージを受け取り、Subscriberに送信するサーバー等のことです。イメージ的には、郵便屋さんみたいなイメージでしょうか。
Broker

私は、ちょっと自由に使えるBrokerが必要だったので、「CloudMQTT」の無料プランを使ってみました!同時接続台数が10台までなのですが、10台も繋ぐ予定はなかったので十分でした。便利!

BrokerをGoogle翻訳にかけると「ブローカ」。うーん。英単語として意味を調べると、「仲介人」みたいな意味合いだそうです。なるほど!

MQTTの仕組み

MQTTの重要な用語も押さえたので、仕組みについて触れていきます!

MQTTでひとつのメッセージを送信する際、まずはPublisherがBrokerにメッセージを送ります(Pubする、とか言ったりします)。そして、BrokerがSubscriber達にメッセージを配信します。そう、Subscriber「達」なんです!

MQTTのメッセージは1対1のやり取りではない

メールは、ToとかCCとかに宛先を追加すれば、1通のメールを複数の相手に送信できますね。でも、これは増えた宛先に対しても送信処理を繰り返し行なっているだけで、メールは基本的に1対1のやり取りです。

MQTTでは、PublisherがPublishしたメッセージを、BrokerがSubscriber達に配信します。Subscriberはひとつだけかもしれないし、100かもしれません。とにかく、複数のSubscriberにメッセージを配信することができます。でも、Publisher側で何か処理が変わる、ということはありません。例え2万のSubscriberがいても、それによってPublisherに負荷がかかるようなこともないんです。(Brokerには負荷がかかります)

MQTTは、1対多のやり取りなんですね!もちろん、Subscriberがひとつだけなら、1対1の通信ということになります。
MQTTのイメージ

こうして見ると、Publisherが「出版社」というのも納得ですね。Publisherが「出版」したメッセージを、Brokerが「配信」している、という感じですね!

Topicを指定してSbscribe

すいません、ややこしくなるので先ほどは書きませんでしたがもうひとつ、「Topic(トピック)」という重要な用語が出てきます。これは、メッセージの種類の指定です。Publishする時もSubscribeする時も、必ずこの「Topic」を指定する必要があります。Publisherの指定したTopicをSubscriberも指定しないと、メッセージを受け取ることができません。Topicは、「話題、テーマ」などといった意味の英単語です。

TopicはどのようにMQTTで使われるのでしょうか。例えば、ある学校の「学級情報」をMQTTで毎日送信していたとします。すると、Topicはこんな感じになります。

school/grade3/class6/female

「学校」の「3年生」の「6クラス」の「女性」つまり3年6組女子のメッセージを指定しているわけですね。他の例も見てみましょう。

school/grade1/class2/male

これだと、1年2組男子のメッセージを指定している、ということになります。

Publisherは学校中のクラス分のメッセージを送信していて、Subscriberは欲しいメッセージだけを選択・指定して受信することができるんです!
Topicのイメージ

ワイルドカード「+」と「#」

Topic指定には、ワイルドカード「+」「#」を使用することができます。例えば、「学年は問わないし、クラスも問わない。とりあえず男子のメッセージ全部がほしい」時は、次のようにTopicを指定します。

school/+/+/male

「+」で指定した部分は、なんでも当てはまるわけですね。でも、次のような使い方はダメです。

school/grade2/class+/male

Topicは「/」を区切り文字としています。「トピック・レベル・セパレーター」と言うみたいです。トピックレベルというのは、「grade2」とか「class5」とか、「/」で区切られた区間そのものを言います。ワイルドカード「+」は、「このトピックレベルはなんでもいい」みたいな使い方をするのであって、「文字の代わりになる」わけではありません。「+」は何回使ってもOKです。

「+」の他にもうひとつ、「#」もワイルドカードになると書きましたが、「#」は「+」と働きが少し異なります。例えばこんな使い方になります。

school/grade2/#

これは、「2年生のメッセージが全部欲しい」ということになります。「grade2」以降のトピックレベルは一切問わないので、「#」で省略してしまっているんですね。これは、次の書き方と同じ意味になります。

school/grade2/+/+

「+」は、ひとつのトピックレベルを「なんでもいいよ」という意味にします。「#」は、「#」以降のトピックレベルが何個あったとしても「全部なんでもいいよ」という意味になります。なので、「#」は次のような使い方はできません。

school/#/male

「#」を一度書いてしまったら、それ以降に何か文字を書く事はできません。これ以降全部省略!という意味ですからね。そういう時は「+」を使いましょう。逆に、Topicに「#」一文字だけ指定すると、すべてのメッセージを受信することができます。

実はTopicには何を書いてもいい

「書き方のルール」みたいなのを書いておいてアレなんですが…。Topicには何書いてもいいんです、実は。例えば次のようなTopicを指定しても、PublisherとSubscriberがどちらも同じTopicを指定していればメッセージは届きます。

トピック:やっほーーーーー

日本語でも届きます(もちろん、Topic指定するためには日本語入力が可能な環境でなければいけませんが)。ただし、区切り文字「/」が入っていないので、このTopicは「トピックレベルが1階層しか無いよ」ということになります。「トピック:やっほーーーーー」という名前のトピックレベルがひとつあるだけ、ということです。ワイルドカードの使用を考えると、不便ではあります。「/」が入っていれば、別に日本語でトピックレベルを指定しても問題無いです。日本語で指定するメリットはちょっとわからないですけれどね!

Brokerへの接続

では、Topicの仕組みもわかったところで、実際どのようにメッセージを送るのでしょうか?

Publisher、Subscriber、どちらもBrokerに接続する必要がありますが、接続の方法は様々です。スマホで「MQTT」というキーワードでアプリを検索すると、色々とアプリが出てきます。これらをインストールして、必要な情報を入力するだけでも、お手軽にBrokerに接続することができます。

また、私はRuby、PHPで試してみたのですが、どちらもMQTTのライブラリが提供されていて、簡単に接続ができました!VPS等、自前のサーバーに機能として組み込みたい場合などにとても便利です!

Brokerに接続ができたら、あとはTopic、メッセージを指定してPublish、もしくは、Topicを指定してSubscribeすればOKです!

Brokerへの接続に必要な情報

大抵の場合、Brokerへの接続には以下の情報が必要です。

  • Brokerのホスト名
  • 接続するポート番号
  • クライアント名
  • ユーザー名
  • パスワード
ホスト名とポート番号

ホスト名は、brokerをネットワーク上で発見するために必要な情報です。どこかのBrokerを登録して使うなら、必ず情報画面のようなところに載っていると思います。もし自前でVPSなどにBrokerを立てたのなら、VPSのホスト名を入力することになります。もしくは、IPアドレスでもいいです。

ポート番号は、brokerによってまちまちなので、これも確認しましょう。これも情報画面のようなところに載っているはずです。ポート番号が合っていないと、アクセスを弾かれてしまいます。

クライアント名

なんでもいいです。これは、Broker側で「今誰がうちにアクセスしてるんだろう?」というのを識別するために使います。

試しにiPhoneのMQTTアプリで、クライアント名に日本語で「わーい」と指定してみましたが、普通に接続できました。

同時に、同じクライアント名で2台以上接続することはできません!

自分で好きに決めていいですが、他に接続する予定の機器と被らないようにしましょう。

ユーザー名、パスワード

ユーザー名とパスワードは、どこかのBrokerを登録して使うなら、登録後に発行されるはずです。CloudMQTTなら、インスタンスを作成後、インスタンスごとに発行されます。自前で立てたBrokerなら、自分で設定しておくことになると思います。

ちなみにインスタンスというのは、「予め決めておいた型」を実際に使って作ったもの、です。今回の場合、「Broker」という型を予め設定しておいて、この型を使って実際に「Broker」というインスタンスを作った、みたいな感じです。

起業したら従業員を雇ったりしますが、「正社員」とか「バイト」とか、型を予め決めておいて、いざ実際に雇う時は、田中さんは正社員、山田くんはバイト、みたいに、この型を使って雇う、みたいな…。すいません、この話は別の記事にするべきですね。話が逸れます。

MQTTの利用例

MQTTの仕組みも見えたところで、利用例をいくつか挙げてみます!

チャット

まず、チャットです!チャットは基本的に1対1ではなく、多人数で行なうことも想定していますね。みんなでワイワイ話しているように見えますが、MQTTを利用したチャットの場合、細かく見ていくと次のようになっています。

誰か一人がメッセージを打つ(Publish)
→チャットのサーバー(Broker)がメッセージを配信
→チャットルームの全員がメッセージを受け取る(Subscribe)

これを、誰かひとりがチャットで発言する度に行なっているんですね!

IoT

IoTの通信は、MQTTが主に使われているんです

例えば、家のエアコンを出先から操作するとして、メールを送る、HTTPでアクセスする、等も考えられますが、一番てっとり早くかつ安全なのは、MQTTで情報を送信することです。

メールを送る場合、メールをトリガーにしてアクションを起こす必要があり、手間がかなりかかります。また、HTTPでアクセスするということは、自宅のラズパイ等を常にインターネット上に公開しておかなければなりません。これもセキュリティ対策などを考えるとかなりの手間です。また、出先から常にラズパイにHTTPアクセスできるようにするには、グローバルIPを固定化(月7000円くらいかかるみたい)するか、ダイナミックDNSというのを設定する必要があります。どちらも手間だし、コストもかかります。

ひとつの例として、以下のような経路での操作方法を考えてみました。

出先からレンタルサーバーにHTTPアクセスし、ボタンを押す
→ボタンを押されたらPHPにPOSTし、MQTTでPublish
→CloudMQTT等のBrokerにメッセージが行く
→自宅のラズパイにRuby等でSubscriberを常駐させておいて、MQTTでメッセージを受け取ったらエアコンを操作する

これなら、ラズパイをインターネット上に公開することなく、出先から操作ができます。操作ができたという報告が欲しいなら、ラズパイから自動でPublishするようにしておけばOKです。もしくは自動でツイートさせるとか。やり方は色々ありますね。

LoRaWANデバイス

LoRaWANデバイスで取得したデータは、日本では920MHz帯を使用して、基地局に送られます。基地局で取得したデータはサーバーへと送られ、MQTTでPublishされます。

私たちがLoRaWANデバイスを実際に使う時は、MQTTでSubscribeすればデータを取得することができるんですね!これはとっても便利です!データの取得さえできれば、あとは好きな形に加工したり、データの取得をトリガーとして何かアクションを起こしたり、色々なことができます。

まとめ

かなり長い記事になっちゃいました…。個人的にMQTTを勉強する上でわかりにくかったところを詳しく書いてみました。
時間ができたら、出先からのエアコン操作にチャレンジしたい!
がんばるぞー!

さき