MQTTに触れてみた その2
前回から引き続き。 kta-m.hatenablog.com
ワイルドカード
前回のおさらい。
Topicはhoge/piyo/fugaといった階層構造で指定します。 Subscriberの指定にはワイルドカードが使えるので、柔軟な受け取り指定が可能です。
使えるワイルドカードは以下の2種類。
前回からのコードはそのまま。Brokerもそのまま。
terminal1
$ ruby subscriber.rb hoge/piyo/fuga
terminal2
$ ruby subscriber.rb hoge/piyo/#
terminal3
$ ruby subscriber.rb hoge/+/fuga
terminal4からいろいろメッセージを配信してみる。
$ ruby publisher.rb hoge/piyo/fuga message
とすると全てのsubscriberが受信。
$ ruby publisher.rb hoge/piyo/fugafuga message $ ruby publisher.rb hoge/piyo/fuga/hogehoge message
とするとterminal2のsubscriberのみ受信
$ ruby publisher.rb hoge/piyopiyo/fuga message
とするとterminal3のsubscriberのみ受信します。
Will
未来形のアレじゃなくて、「遺言」って意味の名詞らしい。
client起動時にbrokerにwillのデータを登録しておくと、 そのclientとの通信が途切れた際に、登録されたwillのメッセージを配信してくれるしくみです。 publisherとの通信が途切れたことをsubscriberに伝えるのがメインの使い方みたい。
ちなみに通信状態の確認は、一定間隔でclientにpingを送ることで確認しているとのこと。
publisher側のコードを次のように変更します。
connectに渡す値にwill_topic
とwill_payload
が加わりました。
その名の通りwillのtopicと、payload(メッセージ)です。
require "mqtt" topic = ARGV[0] message = ARGV[1].dup MQTT::Client.connect(host: "127.0.0.1", port: 1883, will_topic: "error/disconnect", will_payload: "突然の死!") do |c| loop do c.publish(topic, message) sleep(1) end end
terminal1
$ ruby subscriber.rb hoge/piyo/fuga
terminal2
$ ruby subscriber.rb error/#
terminal3
$ ruby publisher.rb hoge/piyo/fuga message
とすると、terminal1で、hoge/piyo/fuga: message
が1秒おきに出てきます。
ここでおもむろにterminal3でCtrl+C
を押すと、terminal2にメッセージが来ます。
error/disconnect: 突然の死!
次回
RetainとかDurable Subscribeを試してみる。 QoSは…なんだか試しにくい気がする。
MQTTに触れてみた その1
奥様に1日坊主と言われて久しいですが、ちゃんとこうやって書く気はあるんですよ。
MQTT
さて、今日はMQTT(MQ Telemetry Transport)というものに触れてみました。 きたるIoT時代に大活躍しそうだと噂のプロトコルです。
多くのデバイスに向けて同期的にメッセージを配信することに特化していて、 お互いにメッセージを配信し合えばリアルタイムな双方向通信もできちゃう! FacebookMessengerにも使われているんだそうな。
ちなみにMQ
が何なのかは…謎です。
特徴
以下のような特徴を持っているので、 ネットワークが不安定だったり非力だったりといった困ったデバイスでもなんとかなるようになってるみたい。
- ヘッダが軽量かつシンプルなので、通信量や処理負荷が比較的小さい
- 通信している相手の接続が途切れたら教えてくれる(Will)
- 配信に途中参加しても、配信済みの最新のメッセージを受け取れる(Retain)
- 接続が途切れても、あとで受け取り損ねたメッセージを受け取れる(Durable Subscribe)
- 状況に応じてメッセージの到達保証のレベルを指定できるので、わりとどうでもいいところに無駄なリソースを割かないようにできる(QoS)
説明してくれてるところがたくさんあるので、詳細は以下を参照してください。
大雑把に説明
登場人物
- Broker:メッセージを管理するサーバー。メッセージを受け取って、それを欲している端末に送る。
- Client:メッセージを送受信する端末
- Publisher:メッセージを送信しようとしているときにこう呼ばれる
- Subscriber:メッセージを受信しようとしているときにこう呼ばれる
Topic
メッセージにはそれぞれTopicと呼ばれるデータを設定します。
SubscriberはどのTopicのメッセージが欲しいかBrokerに伝えておけば、 Brokerがそれに応じたメッセージを配信してくれるという寸法。
Topicはhoge/piyo/fuga
といった階層構造で指定します。
Subscriberの指定にはワイルドカードが使えるので、柔軟な受け取り指定が可能です。
使えるワイルドカードは以下の2種類。
hoge/piyo/#
:piyo以降は何でもOKhoge/+/fuga
:+の部分は(1階層分)何でもOK
インストール
今回は、BrokerとしてMosquitto、Clientとしてruby-mqttを使用します。
Broker
Macで試すのでhomebrewでインストール。
$ brew install mosquitto
Client
ruby-mqttをインストール
$ gem install mqtt
とりあえずこれで準備完了。
基本の動き
Client実装
Publisher
require "mqtt" topic = ARGV[0] message = ARGV[1].dup MQTT::Client.connect(host: "127.0.0.1", port: 1883) do |c| c.publish(topic, message) end
Subscriber
require "mqtt" request_topic = ARGV[0] MQTT::Client.connect(host: "127.0.0.1", port: 1883) do |c| c.get(request_topic) do |topic,message| puts "#{topic}: #{message}" end end
動かしてみる
terminal0でBrokerを起動
$ /usr/local/opt/mosquitto/sbin/mosquitto
terminal1
$ ruby subscriber.rb hoge
terminal2
$ ruby publisher.rb hoge Hello_MQTT!
terminal1側で受信!
hoge/piyo: Hello_MQTT!
次回
とりあえず最低限動くところまで書けたので今日はここまで。 次回はワイルドカードとかWillとか試してみる。
実に楽しみだ
いきなりですが、あけましておめでとうございます。
今年はブログを書いてみようと思い立って、新年早々開設してみました。
とりあえず書きたいことは、
主な動機は、今年いくつかgemを作って公開するつもりでいるから。 今まで技術的なことはQiitaに書いてきたけど、 OSSとしてライブラリを公開するにあたっては、以下の利点があると会社の先輩談。
- ライブラリと個人が紐づく
- README.mdよりも使い方の説明がしやすい
- 今後の展望・苦労した点などを気軽にぼやける
確かにそうだなーと思いつつ、お正月というちょうどいい区切りもあったので、満を持して始めちゃいます。 1年後には全く違うものになってるかもしれないけど、気の向くままにやっていきます。
どうそ、よろしくお願いします!