センサーはどうやってスマホに知らせるの?
ドアのセンサー、温度計、あなたのスマホは、それぞれ別の機器です。センサーはスマホがあることを知らなくてよく、スマホも何度も問い合わせなくてすむのが理想です。MQTT という小さなメッセージの仕組みがこれを解決します。機器はメッセージを仲介役に預け、興味のある人がそれを受け取ります。
このレッスンの終わりに
メモ
トピックを使って、機器が MQTT ブローカーに送ったメッセージを読むことができます。
キーワード
- ブローカー(broker):すべてのメッセージを受け取り、届け先に渡す仲介役。
- パブリッシュ(発行):トピックという名札をつけて、ブローカーにメッセージを送ること。
- サブスクライブ(購読):聞きたいトピックをブローカーに伝えること。
- トピック(topic):メッセージの名札。
home/door/stateのように、道筋の形で書きます。 - 保持メッセージ(retained):トピックの最後のメッセージ。ブローカーが覚えておき、あとから購読した人に渡します。
- ワイルドカード:購読のときに、複数のトピックに合う記号。
はじめに:もう知っていること
メモ
頭の中で答えてみましょう。1. /home/kim/notes.txt というパスは何でできていますか。2. 手紙をポストに入れるとき、誰が読むかを知っている必要はありますか。3. ファイルを一覧にするとき、*.txt の * は何を表しますか。この 3 つの考えは、このレッスンでもう一度出てきます。答え:スラッシュで区切ったフォルダー名とファイル名。いいえ、宛先だけあればよい。どんな文字でも。
始める前に
メモ
レッスンの上のバーにある ラボを開始 を押し、動いていると表示されるまで待ちます。コンテナはふたつあります。ずっとメッセージを送り続ける sensors と、それを中継する broker です。ブラウザーで開く画面はないので、ターミナルを使います。docker exec broker は、ブローカーの中でコマンドをひとつ実行する命令です。下の 実行 ボタンは、それぞれのコマンドをラボのターミナルに、同じセッションの中で順番に入力します。様子を見たいときや自分で入力したいときは、バーの ターミナルを開く(新しいタブ) を押します。
購読すると、発行されたものが聞こえる
このコマンドは home/# を購読します。home の下のすべてのトピックという意味です。-v は各メッセージの前にトピックを表示し、-C 8 は 8 件で、-W 10 は 10 秒で止まるので、必ず終わります。各行は、トピック、空白、値の順です。センサーの 4 つのトピックが見えます。ふたつの温度と湿度は整数で、ドアの状態は open か closed です。最初に届く行は保持メッセージで、理由はあとで出てきます。正確な数字は実行を押した秒によって変わるので、あなたの結果は違って当然です。
docker exec broker mosquitto_sub -t 'home/#' -v -C 8 -W 10ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
トピックは道筋で、ワイルドカードはその一部に合う
トピックは、フォルダーのように階層ごとに書きます。# は、いま使ったとおり、その下のすべての階層に合います。+ は、ちょうどひとつの階層に合います。だから home/+/temperature は、どの部屋の温度にも合います。3 行が出て、各行は home/kitchen/temperature か home/livingroom/temperature で始まり、整数で終わります。湿度とドアは型に合わないので出ません。
docker exec broker mosquitto_sub -t 'home/+/temperature' -v -C 3 -W 10ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
保持メッセージは、遅れて来た購読者を待っている
これはドアを聞いて、メッセージをひとつだけ求めます。すぐに 1 行、home/door/state のあとに open か closed が返ります。ドアのセンサーがメッセージを保持にしていて、ブローカーが最後のひとつを覚えておき、購読した人に渡すからです。次に、保持されていない湿度と比べましょう。新しい購読者は、センサーが次に発行するまで何も聞こえないので、答えが出るまで最大で 1 秒ほど長くかかり、そのあと整数のついた 1 行が出ます。
docker exec broker mosquitto_sub -t home/door/state -v -C 1 -W 5ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
docker exec broker mosquitto_sub -t home/livingroom/humidity -v -C 1 -W 5ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
確認
ヒント
なぜドアはすぐに答えて、湿度は待ったのでしょうか。答え:ドアのメッセージは保持されていて、ブローカーがすでに最後のひとつを持っていたからです。湿度は、発行されたそのときにだけ届きます。
自分でも発行できる
ブローカーに届く人なら、誰でも発行できます。このコマンドは、自分用のトピック home/notes/first に hello from me を発行し、-r で保持にします。何も表示されません。そのあと読み返すと、答えは毎回かならず home/notes/first hello from me です。あなたのメッセージが、そのトピックの最後だからです。
docker exec broker mosquitto_pub -t home/notes/first -r -m 'hello from me'ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
docker exec broker mosquitto_sub -t home/notes/first -v -C 1 -W 3ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある思い込み
注意
購読者がセンサーに「いまの値は?」と尋ねる、と思う人が多いのですが、違います。センサーは好きなときに発行し、ブローカーはその時点で購読している人にだけ渡します。だから保持メッセージがあるのです。そして「保持」は「ずっと残る」という意味ではありません。そのトピックの次のメッセージで置きかわり、このラボのブローカーは止まるとすべて忘れます。
このラボが省いていること
本物の機器は、ネットワークをこえてブローカーにつなぎます。名前とパスワードか証明書で本人を示し、通信は暗号化されて、途中の誰にもメッセージを読まれたり書きかえられたりしません。このラボはそれをすべて省いています。あなたのコピーの中にいる人なら、誰でも何でも読み書きできます。ここで安全なのは、コピーの外から届くものがないからにすぎません。本物のブローカーをこのようにしてはいけません。
最後の確認
ヒント
見返さずに答えましょう。1. センサーはメッセージを誰に送りますか。2. トピックとは何ですか。3. home/+/temperature は何に合い、home/# は何に合いますか。4. 保持メッセージは何をしますか。答え:ブローカーに送る。購読者に直接は送らない。メッセージの名札で、道筋の形で書く。どれかひとつの部屋の温度と、home の下のすべてのトピック。ブローカーが最後のひとつを覚えておき、あとから購読した人に渡す。
先生へ
ヒント
このレッスンは、ラボで進めるレッスンの小さな例です。手順と実行ボタンがレッスンで、ラボは生徒ひとりひとりのコピーです。ラボは同じネットワーク上のふたつのコンテナ、標準の MQTT ブローカーと、架空のセンサーのスクリプトです。ここでは何も自動採点されません。生徒は、実行したコマンドとその出力、そして保持メッセージが何の役に立つかを一文で提出します。要点:1. ブローカーは、発行する側と購読する側の間に入る。2. トピックは道筋で、+ と # はワイルドカード。3. 保持メッセージは最後のひとつで、遅れて来た購読者のために残される。よくある思い込み:購読者がセンサーに値を尋ねると考えること。用意するもの:ラボとそのターミナル。ヒント:実行する前に、ワイルドカードで何行出るかを予想させましょう。値は決まった周期で変わりますが、いまどこにいるかは生徒が実行を押す時刻で決まるので、二人の生徒は違う数字を見ます。ラボは、本物のネットワークに必要なサインインと暗号化を省いています。クラスで話し合うのによい問いです。