カテゴリ: dev
MQTT とは TCP/IP 上で動作する通信プロトコルの名称で、HTTP よりも軽量・省電力という特徴がある。その特徴から消費電力・通信量の制約を受けやすい IoT デバイスとサーバー間での通信に向いており、仕様標準化も進んでいる。@moznion さんが言及 されているのを見て興味を持ち、Ruby で試してみた。Ruby では mqtt
という gem が用意されており、手軽に試すことが出来る。
$ gem install mqtt --no-ri --no-rdoc
画像出典: Securing MQTT - BuildingIoT 2016 slides
MQTT プロトコルにおける通信では、データ送信元と送信先との間に Broker
と呼ばれるサーバが介在する。データ送信者(Publisher
と呼ばれる) はデータ受信者に対して直接データを送信するのではなく Broker
に対してデータを送信し、Broker
はそれを各受信者(Subscriber
)に対して送信する。
MQTT 通信の試用環境としてオープンな(誰でも subscribe できる) Broker が用意されており、今回はこれを使うこととする。
MQTT プロトコルでデータを送受信する際には、Topic を指定する必要がある。Topic は最低 1 文字の ASCII で、大文字・小文字を区別する。詳しくは 仕様を確認 のこと。
ターミナルで pry
を開き、以下のようにして Subscriber を立ち上げる。alea12/#
というのは Topic Filter と呼ばれるもので、正規表現ほどの表現力はないものの、一定のワイルドカード的な用途に使える。
[1] pry(main)> require 'mqtt' => true [2] pry(main)> server = 'test.mosquitto.org' => "test.mosquitto.org" [3] pry(main)> channel = 'alea12/#' => "alea12/#" [4] pry(main)> MQTT::Client.connect(server).get(channel) do |topic, msg| [4] pry(main)* puts "[#{Time.now}] #{topic}: #{msg}" [4] pry(main)* end
Subscriber を立ち上げると、指定した Channel への Publish 待ち状態となる。このターミナルはこのまま残しておく。
別のターミナルを立上げ、以下のようにすることで指定した Channel に対してメッセージを送信することができる。
[1] pry(main)> require 'mqtt' => true [2] pry(main)> MQTT::Client.connect('test.mosquitto.org').publish('alea12', 'Hello, world!') => nil [3] pry(main)> MQTT::Client.connect('test.mosquitto.org').publish('alea12/test', 'Hello world, again!') => nil
先ほどのターミナルに戻って確認すると、以下のように送信したデータが受信できているはず。
[2017-11-13 10:32:32 +0900] alea12: Hello, world! [2017-11-13 10:32:41 +0900] alea12/test: Hello world, again!
Ruby で MQTT お手軽に試すことができて良かった
— Kimiyasu Morikawa (@alea12) 2017年11月13日