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 ---> |  |
                +--+
-------------------------------------

関連資料・記事

参考サイト

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で終了させる。

関連資料・記事

参考サイト