Mosquitto
2016/11/12更新
対応バージョン: 1.4.8
MosquittoのPub/Sub通信において、Publisher・SubscriberそれぞれのQoSのレベルによって通信フローが異なるので整理する。QoSには0,1,2の3種類があり、数字が大きくなるほどフローが厳格になる。
0 : 最高1回。到着保証なし
1 : 最低1回。到着保証あり(重複到着の可能性あり)
2 : 正確に1回。到着保証あり
以下、SubscriberのQoSが0,1,2それぞれの場合におけるPublisherのQoSが0,1,2の場合の通信フローを示す。
SubscriberのQoS = 0
Subscriberの待受
% mosquitto_sub -d -t test Client mosqsub/5996-n1 sending CONNECT Client mosqsub/5996-n1 received CONNACK Client mosqsub/5996-n1 sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 0) Client mosqsub/5996-n1 received SUBACK Subscribed (mid: 1): 0 : (60秒毎にping) lient mosqsub/5996-n1 sending PINGREQ Client mosqsub/5996-n1 received PINGRESP :
PublisherのQoS = 0
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" Client mosqpub/6366-n1 sending CONNECT Client mosqpub/6366-n1 received CONNACK Client mosqpub/6366-n1 sending PUBLISH (d0, q0, r0, m1, 'test', ... (5 bytes)) Client mosqpub/6366-n1 sending DISCONNECT
Subscriberの受信状況
Client mosqsub/5996-n1 received PUBLISH (d0, q0, r0, m0, 'test', ... (5 bytes)) hello
通信フロー
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | ----> PUBLISH DISCONNECT ---> | | +--+ -------------------------------------
メッセージPUBLISH時のBrokerの動作
・SubscriberにメッセージをPUBLISH
PublisherのQoS = 1
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" -q 1 Client mosqpub/6789-n1 sending CONNECT Client mosqpub/6789-n1 received CONNACK Client mosqpub/6789-n1 sending PUBLISH (d0, q1, r0, m1, 'test', ... (5 bytes)) Client mosqpub/6789-n1 received PUBACK (Mid: 1) Client mosqpub/6789-n1 sending DISCONNECT
Subscriberの受信状況
Client mosqsub/5996-n1 received PUBLISH (d0, q0, r0, m0, 'test', ... (5 bytes)) hello
通信フロー
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | ----> PUBLISH PUBACK <----- | | | | DISCONNECT ---> | | +--+ -------------------------------------
メッセージPUBLISH時のBrokerの動作
・メッセージを保存
・SubscriberにメッセージをPUBLISH
・メッセージを削除
PublisherのQoS = 2
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" -q 2 Client mosqpub/7609-n1 sending CONNECT Client mosqpub/7609-n1 received CONNACK Client mosqpub/7609-n1 sending PUBLISH (d0, q2, r0, m1, 'test', ... (5 bytes)) Client mosqpub/7609-n1 received PUBREC (Mid: 1) Client mosqpub/7609-n1 sending PUBREL (Mid: 1) Client mosqpub/7609-n1 received PUBCOMP (Mid: 1) Client mosqpub/7609-n1 sending DISCONNECT
Subscriberの受信状況
Client mosqsub/5996-n1 received PUBLISH (d0, q0, r0, m0, 'test', ... (5 bytes)) hello
通信フロー
Subscriber側のカッコ内のPUBLISHは前半か後半のどちらか一方で発生する。
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | (---> PUBLISH) PUBREC <----- | | | | PUBREL -----> | | | | (---> PUBLISH) PUBCOMP <----- | | | | DISCONNECT ---> | | +--+ -------------------------------------
メッセージPUBLISH時のBrokerの動作
以下のいずれか
(パターン1)
・メッセージを保存
(パターン2)
・メッセージIDを保存
・SubscriberにメッセージをPUBLISH
PUBREC時のBrokerの動作
・PublisherにメッセージIDを返す
PUBREL時のBrokerの動作
以下のいずれか
(パターン1)
・SubscriberにメッセージをPUBLISH
・メッセージを削除
(パターン2)
・メッセージIDを削除
PUBCOMP時のBrokerの動作
・PublisherにメッセージIDを返す
SubscriberのQoS = 1
Subscriberの待受
% mosquitto_sub -d -t test -q 1 Client mosqsub/8528-n1 sending CONNECT Client mosqsub/8528-n1 received CONNACK Client mosqsub/8528-n1 sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 1) Client mosqsub/8528-n1 received SUBACK Subscribed (mid: 1): 1 : (60秒毎にping) Client mosqsub/8528-n1 sending PINGREQ Client mosqsub/8528-n1 received PINGRESP : (60秒毎にping) :
PublisherのQoS = 0
この場合の動作はSubscriberのQoSが0の時と同じなので割愛する。
PublisherのQoS = 1
この場合、SubscriberのQoSが0の時と違うのはSubscriberがPUBLISHを受け取った後にPUBACKを返す部分だけである。
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" -q 1 Client mosqpub/9460-n1 sending CONNECT Client mosqpub/9460-n1 received CONNACK Client mosqpub/9460-n1 sending PUBLISH (d0, q1, r0, m1, 'test', ... (5 bytes)) Client mosqpub/9460-n1 received PUBACK (Mid: 1) Client mosqpub/9460-n1 sending DISCONNECT
Subscriberの受信状況
Client mosqsub/8528-n1 received PUBLISH (d0, q1, r0, m1, 'test', ... (5 bytes)) Client mosqsub/8528-n1 sending PUBACK (Mid: 1) hello
通信フロー
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | ----> PUBLISH | | <---- PUBACK ※SubscriberのQoSが1か2の場合に返す PUBACK <----- | | | | DISCONNECT ---> | | +--+ -------------------------------------
PublisherのQoS = 2
この場合、SubscriberのQoSが0の時と違うのはSubscriberがPUBLISHを受け取った後にPUBACKを返す部分だけである。
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" -q 2 Client mosqpub/9838-n1 sending CONNECT Client mosqpub/9838-n1 received CONNACK Client mosqpub/9838-n1 sending PUBLISH (d0, q2, r0, m1, 'test', ... (5 bytes)) Client mosqpub/9838-n1 received PUBREC (Mid: 1) Client mosqpub/9838-n1 sending PUBREL (Mid: 1) Client mosqpub/9838-n1 received PUBCOMP (Mid: 1) Client mosqpub/9838-n1 sending DISCONNECT
Subscriberの受信状況
Client mosqsub/8528-n1 received PUBLISH (d0, q1, r0, m2, 'test', ... (5 bytes)) Client mosqsub/8528-n1 sending PUBACK (Mid: 2) hello
通信フロー
Subscriber側のカッコ内のPUBLISH & PUBACKの組み合わせは前半か後半のどちらか一方で発生する。
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | (---> PUBLISH) | | (<--- PUBACK) ※SubscriberのQoSが1か2の場合に返す PUBREC <----- | | | | PUBREL -----> | | | | (---> PUBLISH) | | (<--- PUBACK) ※SubscriberのQoSが1か2の場合に返す PUBCOMP <----- | | | | DISCONNECT ---> | | +--+ -------------------------------------
SubscriberのQoS = 2
Subscriberの待受
% mosquitto_sub -d -t test -q 2 Client mosqsub/7238-n1 sending CONNECT Client mosqsub/7238-n1 received CONNACK Client mosqsub/7238-n1 sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 2) Client mosqsub/7238-n1 received SUBACK Subscribed (mid: 1): 2 : (60秒毎にping) Client mosqsub/7238-n1 sending PINGREQ Client mosqsub/7238-n1 received PINGRESP : (60秒毎にping) :
PublisherのQoS = 0
この場合の動作はSubscriberのQoSが0および1の場合と同じなので割愛する。
PublisherのQoS = 1
この場合の動作はSubscriberのQoSが1の場合と同じなので割愛する。
PublisherのQoS = 2
この場合、SubscriberのQoSが1の時と違うのはSubscriberがPUBLISHを受け取った後にPUBACKではなくPUBREC,PUBREL,PUBCOMPを返す部分だけである。
Publisherからメッセージ送信
% mosquitto_pub -d -t test -m "hello" -q 2 Client mosqpub/8197-n1 sending CONNECT Client mosqpub/8197-n1 received CONNACK Client mosqpub/8197-n1 sending PUBLISH (d0, q2, r0, m1, 'test', ... (5 bytes)) Client mosqpub/8197-n1 received PUBREC (Mid: 1) Client mosqpub/8197-n1 sending PUBREL (Mid: 1) Client mosqpub/8197-n1 received PUBCOMP (Mid: 1) Client mosqpub/8197-n1 sending DISCONNECT
Subscriberの受信状況
lient mosqsub/7238-n1 received PUBLISH (d0, q2, r0, m2, 'test', ... (5 bytes)) Client mosqsub/7238-n1 sending PUBREC (Mid: 2) Client mosqsub/7238-n1 received PUBREL (Mid: 2) hello Client mosqsub/7238-n1 sending PUBCOMP (Mid: 2) hello
通信フロー
Subscriber側のカッコ内のPUBLISH & PUBREC & PUBREL & PUBCOMPの組み合わせは前半か後半のどちらか一方で発生する。
Publisher Broker Subscriber ------------------------------------- +--+ CONNECT -----> | | CONNACK <----- | | | | PUBLISH -----> | | | | (---> PUBLISH) | | (<--- PUBREC) ※SubscriberのQoSが2の場合に返す | | (---> PUBREL) ※SubscriberのQoSが2の場合に返す PUBREC <----- | | | | PUBREL -----> | | | | (---> PUBCOMP) ※SubscriberのQoSが2の場合に返す | | | | (---> PUBLISH) | | (<--- PUBREC) ※SubscriberのQoSが2の場合に返す | | (---> PUBREL) ※SubscriberのQoSが2の場合に返す PUBCOMP <----- | | | | (---> PUBCOMP) ※SubscriberのQoSが2の場合に返す | | DISCONNECT ---> | | +--+ -------------------------------------
関連資料・記事
参考サイト
MQ Telemetry Transport (MQTT) V3.1 プロトコル仕様 (IBM)
MQTTについて詳しく知る (sango)
MQTTで始めるIoTデバイスの作り方 第1回:「MQTT」を知り「Mosquitto」を導入する (MONOist)
MQTTで始めるIoTデバイスの作り方 第2回:MQTTのプロトコルを解析して挙動を理解する (MONOist)
MQTTで始めるIoTデバイスの作り方 第3回:ESP8266でMQTT (MONOist)
Mosquitto技術情報 (Qiita)
MQTT技術情報 (Qiita)
2016/11/11更新
対応バージョン: 1.4.8
MosquittoをUbuntu 16.04にインストールして簡単なPub/Sub通信を行ってみる。インストール
Broker(mosquitto)とPublisher/Subscriber(mosquitto-clients)をインストールする。
% sudo apt install mosquitto mosquitto-clients
インストールが終わるとBrokerは自動的に起動する。
% systemctl status mosquitto ● mosquitto.service - LSB: mosquitto MQTT v3.1 message broker Loaded: loaded (/etc/init.d/mosquitto; bad; vendor preset: enabled) Active: active (running) since 金 2016-11-11 01:15:22 JST; 1min ago Docs: man:systemd-sysv-generator(8) CGroup: /system.slice/mosquitto.service └─10706 /usr/sbin/mosquitto -c /etc/mosquitto/mosquitto.conf
Pub/Sub通信
SubscriberをBrokerに接続しておき、Publisherからメッセージを送信してSubscriberが受信できることを確認する。ここではQoS = 0(デフォルト)、トピック名を「test」とする。
Subscriber接続
mosquitto_subを使用する。-d(デバッグモード)と-t(トピック)を指定してBrokerに接続し、Publisherからのメッセージを待ち受ける。
% mosquitto_sub -d -t test Client mosqsub/11226-zero sending CONNECT Client mosqsub/11226-zero received CONNACK Client mosqsub/11226-zero sending SUBSCRIBE (Mid: 1, Topic: test, QoS: 0) Client mosqsub/11226-zero received SUBACK Subscribed (mid: 1): 0
Publisher接続 & メッセージ送信
mosquitto_pubを使用する。-d(デバッグモード)と-t(トピック)を指定したうえでBrokerに-m(メッセージ)を送信する。
% mosquitto_pub -d -t test -m "hello" Client mosqpub/11242-zero sending CONNECT Client mosqpub/11242-zero received CONNACK Client mosqpub/11242-zero sending PUBLISH (d0, q0, r0, m1, 'test', ... (5 bytes)) Client mosqpub/11242-zero sending DISCONNECT
待ち受けていたSubscriber側で以下の出力が得られればOKである。
Client mosqsub/11226-zero received PUBLISH (d0, q0, r0, m0, 'test', ... (5 bytes)) hello
Subscriber側は60秒おきにBrokerの生存確認を行うのでその際に以下が出力される。
Client mosqsub/11226-zero sending PINGREQ Client mosqsub/11226-zero received PINGRESP
待ち受け状態のmosquitto_subはCtrl + cで終了させる。
関連資料・記事
参考サイト
MQ Telemetry Transport (MQTT) V3.1 プロトコル仕様 (IBM)
MQTTについて詳しく知る (sango)
MQTTで始めるIoTデバイスの作り方 第1回:「MQTT」を知り「Mosquitto」を導入する (MONOist)
MQTTで始めるIoTデバイスの作り方 第2回:MQTTのプロトコルを解析して挙動を理解する (MONOist)
MQTTで始めるIoTデバイスの作り方 第3回:ESP8266でMQTT (MONOist)
Mosquitto技術情報 (Qiita)
MQTT技術情報 (Qiita)