MQTT通信テストツールの便利な使い方

# はじめに
本記事ではMQTT関連で以下のツールのちょっとした便利な使い方を紹介します。  
(Wiresharkはパケットキャプチャツールですが)
- **MQTTX(MQTTクライアント)**
    - 連続Publish、Publish/Subscribe時にメッセージにタイムスタンプなどを追加方法
- **Wireshark(パケットキャプチャ)**
    - MQTT関連の情報(メッセージなど)の表示方法

Publisher - Subscriber間通信のテストやトラブルシューティング時に利用できるかなと思います。
なお、MQTT Brokerは構築済みであることを前提としています。MQTT Brokerの構築手順などには触れません。

# MQTTX
以下のようなことをやりたいときに使えるMQTTXの機能について紹介していきます。
- **Publishをx秒ごとにしたい**
- **Publish/Subscribe時にタイムスタンプをメッセージに追加したい**
- **Publishをx秒ごとにする際に何回目の送信なのかをメッセージに追加したい**

インストール方法やBrokerへの接続方法、基本的なPublish/Subscribe使い方は以下のリファレンスを参照してください。
[MQTTX/manual-jp.md at main · emqx/MQTTX](https://github.com/emqx/MQTTX/blob/main/docs/manual-jp.md)

## Publishをx秒ごとにしたい
`Timed Message`機能でx秒ごとにPublishすることができます。  
Broker接続後、「・・・」をクリックし`Timed Message`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/8309153e-6a01-67d5-d269-498f1d6d7732.png)

すると以下のように`Message frequency(s)`を設定できますので、送信したい間隔(秒)を入力しConfirmをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/45506c47-cebe-9b5a-5135-bcf32ee3d52d.png)

`Timed Message`設定後、通常と同じようにPublishを行うと設定した間隔でPublishをしてくれます。  
以下は`Message frequency`に1秒を指定した場合の例です。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/ac97508f-c588-69cf-c3d1-84b574e43468.png)


停止する際には右上の`Clear timer`アイコンをクリックします。

## Publish/Subscribe時にタイムスタンプをメッセージに追加したい
`Script`機能でメッセージに追加することができます。
左のメニューから下図の赤枠アイコンをクリックすると、Script(Javascript)を記載できる画面に移動できます。  
Scriptに書いたコードに対して`Input`にメッセージを指定してTestすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/8c5e20fb-5485-3c9b-8d03-02ba0bd9b4a1.png)

こちらはメッセージにタイムスタンプを追加するサンプルです。
```js
function handlePayload(value) {
  let _value = value;
  if (typeof value == 'string') {
    _value = JSON.parse(value)
  }
  _value.ts = new Date().toISOString();
  return JSON.stringify(_value);
}

execute(handlePayload)
```

引数valueでメッセージが渡されてきます。Scriptを保存し、Brokerに接続します。
接続後、下図のように「・・・」をクリックし`Run Script`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/8a621543-3c57-9443-5770-4940db7e366c.png)

以下のようなScript設定が表示されるため、`Script name`に先ほど保存したScriptを設定します。  
![mqttx_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/e52c2bf0-ef91-68e6-2fd7-13dd9b7bebe3.png)

`Applied to`には以下のようにいつScriptを反映させるかを指定します。
- `All`: Publish/Subscribe両方
- `Received`: Subscribe時
- `Published`: Publish時

以下はPublish時にScriptを反映した際のPublishです。元のメッセージにタイムスタンプが`ts`フィールドとして追加されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/f2d3a639-51e7-4221-2859-029fc274c44a.png)

Scriptの反映を取り消す場合には右上の`Stop script`アイコンをクリックします。


## Publishをx秒ごとにする際に何回目の送信なのかをメッセージに追加したい
※2022/11にリリースされたv1.9.0で追加されたようです。  
紹介した`Timed Message`と`Script`機能を組み合わせて以下のようにタイムスタンプ以外にも`count(連続送信の何回目なのか)`フィールドも追加して連続Publishすることができます。  
```json
{"val":"hello","client_ts":"2022-12-22T02:28:35.054Z","count":1}
{"val":"hello","client_ts":"2022-12-22T02:28:36.121Z","count":2}
{"val":"hello","client_ts":"2022-12-22T02:28:37.115Z","count":3}
{"val":"hello","client_ts":"2022-12-22T02:28:38.088Z","count":4}
```

以下のようなScriptを作成します。
```js
function handlePayload(value, msgType, index) {
  let _value = value;
  if (typeof value == 'string') {
    _value = JSON.parse(value)
  }
  _value.client_ts = new Date().toISOString();
  _value.count = index;
  return JSON.stringify(_value);
}

execute(handlePayload)
```

PublishedにScriptを反映しTimed Messageを利用した場合に渡される引数の値は以下のようになっています。
| 引数 | 渡される値 |
|:-:|:-:|
| value | メッセージ |
| msgType | 固定値"Publish" |
| index | Timed Messageでの送信回数 |

なので引数indexをcountフィールドとしてメッセージに追加しています。

Script保存後、先ほど紹介したように各機能以下のように設定します。
- `Run Script`: Publish時に反映
- `Timed Message`: x秒ごと

設定後、Publishすると以下のようにx秒ごとにタイムスタンプと送信回数がメッセージに追加されてPublishされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/d3993176-8e78-cca7-d4dd-886d5e2af73f.png)


※公式のScriptのサンプルを参考にしました。以下に数種類あります。
[MQTTX/docs/script-example at main · emqx/MQTTX](https://github.com/emqx/MQTTX/tree/main/docs/script-example)


# Wireshark
今回はキャプチャしたMQTTパケットの中からMQTTに関する情報を表示する方法を紹介します。  
Wiresharkのインストール方法、使い方、キャプチャの方法については触れません。

取得したパケットキャプチャファイルをWiresharkで開きます。
`編集` > `設定`から設定画面を開きます。  
`外観` > `列`メニューを開きます。  
ここから表示する列を追加することができます。以下のようにMQTTのメッセージ、QoS、バージョンの列を追加します。

| 題名| 種別 | フィールド |
|:-:|:-:|:-:|
| mqtt_msg | Custom | mqtt.msg_text |
| mqtt_qos | Custom | mqtt.qos |
| mqtt_ver | Custom | mqtt.ver |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/1e47c949-2f95-5682-37c6-5c3afa78832f.png)

追加後、OKを押しパケット一覧表示画面に戻ると以下のように追加したMQTTの情報が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2959481/a4af5c5d-e66e-ec04-e507-e1d82f0ed6c9.png)

他のMQTTに関する表示を追加したい場合は以下のリファレンスなどを参考にしてみてください。
[Wireshark · Display Filter Reference: MQ Telemetry Transport Protocol](https://www.wireshark.org/docs/dfref/m/mqtt.html)

# おわりに
本記事ではMQTT関連でMQTTXとWiresharkのちょっとした便利な使い方を紹介しました。
これで少しでも作業が楽になったらなと思います！