Skip to content

サブスクリプションフィルターの使い方

このページでは、EMQXでサブスクリプションフィルター機能を有効化し、実際に動作を確認する手順を説明します。MQTTX CLIを使ってパブリッシャーと複数のサブスクライバーをシミュレートし、フィルター式がどのように各サブスクライバーに届くメッセージを制御するかを観察します。

前提条件

開始する前に、以下を準備してください。

  • EMQX 6.2以上が稼働していること
  • MQTTX CLI がインストールされていること

ステップ1:サブスクリプションフィルターを有効化する

サブスクリプションフィルターはデフォルトで無効になっています。無効時は、?文字はトピック文字列の通常の一部として扱われ、既存のサブスクリプションとの完全な互換性が保たれます。

ダッシュボードからの設定

  1. Management -> MQTT Settings -> General タブに移動します。
  2. Subscription Message Filter フィールドを enable に設定します。
  3. Save Changes をクリックします。

変更はブローカーの再起動なしに即時反映されます。

設定ファイルからの設定

emqx.conf に以下を追加します。

hocon
mqtt.subscription_message_filter = enable

変更を反映するにはEMQXを再起動するか、デプロイ環境が対応していれば設定のリロードを行ってください。

REST APIからの設定

bash
curl -s -u key:secret -X PUT \
  -H "Content-Type: application/json" \
  http://localhost:18083/api/v5/configs/mqtt \
  -d '{"subscription_message_filter": "enable"}'

有効化後、クライアントはサブスクリプションにフィルター式を付与できます。構文の詳細や例は、サブスクリプションフィルター概要のFilter Syntaxを参照してください。

ステップ2:サブスクライバーを起動する

この例では、センサーが sensor/1/temperature に温度データをパブリッシュし、各メッセージには location ユーザープロパティが含まれます。3つのサブスクライバーが同じトピックを異なるフィルター式でサブスクライブします。

サブスクライバーサブスクリプション受信するメッセージ条件
sub-roomAsensor/+/temperature?location=roomAlocation=roomA
sub-roomBsensor/+/temperature?location=roomBlocation=roomB
sub-allsensor/+/temperature全メッセージ(フィルターなし)

3つのターミナルを開き、それぞれのサブスクライバーを起動します。

ターミナル1:roomAサブスクライバー

bash
mqttx sub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id sub-roomA \
  -t "sensor/+/temperature?location=roomA"

ターミナル2:roomBサブスクライバー

bash
mqttx sub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id sub-roomB \
  -t "sensor/+/temperature?location=roomB"

ターミナル3:フィルターなしサブスクライバー

bash
mqttx sub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id sub-all \
  -t "sensor/+/temperature"

TIP

--mqtt-version 5 フラグは必須です。サブスクリプションフィルターはMQTT 5.0の機能に依存しています。

ステップ3:Room A向けのメッセージをパブリッシュする

4つ目のターミナルで、User Propertiesに location=roomA を含むメッセージをパブリッシュします。

bash
mqttx pub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id publisher \
  -t "sensor/1/temperature" \
  -m '{"value": 23.5}' \
  --user-properties "location: roomA"

期待される結果:

サブスクライバーメッセージ受信
sub-roomA受信(location=roomAが一致)
sub-roomB非受信(location値が不一致)
sub-all受信(フィルターなし)

ステップ4:Room B向けのメッセージをパブリッシュする

bash
mqttx pub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id publisher \
  -t "sensor/1/temperature" \
  -m '{"value": 19.1}' \
  --user-properties "location: roomB"

期待される結果:

サブスクライバーメッセージ受信
sub-roomA非受信(location値が不一致)
sub-roomB受信(location=roomBが一致)
sub-all受信(フィルターなし)

ステップ5:複数条件(AND論理)のテスト

サブスクリプションフィルターは & で複数条件を結合できます。locationunit の両方が一致する必要がある新しいサブスクライバーを起動します。

bash
mqttx sub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id sub-roomA-celsius \
  -t "sensor/+/temperature?location=roomA&unit=celsius"

両条件を満たすメッセージをパブリッシュします。

bash
mqttx pub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id publisher \
  -t "sensor/1/temperature" \
  -m '{"value": 22.0}' \
  --user-properties "location: roomA" \
  --user-properties "unit: celsius"

sub-roomA-celsius サブスクライバーはメッセージを受信します。次に、unit が不一致のメッセージをパブリッシュします。

bash
mqttx pub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id publisher \
  -t "sensor/1/temperature" \
  -m '{"value": 71.6}' \
  --user-properties "location: roomA" \
  --user-properties "unit: fahrenheit"

sub-roomA-celsius サブスクライバーは、このメッセージを受信しません。location=roomA は一致しても、unit 条件が満たされていないためです。

ステップ6:ユーザープロパティなしのメッセージをパブリッシュする

ユーザープロパティなしのメッセージをパブリッシュします。

bash
mqttx pub -h localhost -p 1883 \
  --mqtt-version 5 \
  --client-id publisher \
  -t "sensor/1/temperature" \
  -m '{"value": 20.0}'

期待される結果:

サブスクライバーメッセージ受信
sub-roomA非受信(locationキーが存在しない)
sub-roomB非受信(locationキーが存在しない)
sub-all受信(フィルターなし)

これは、必要なユーザープロパティキーが欠落している場合、フィルター式付きサブスクリプションのメッセージは除外されることを示しています。

まとめ

シナリオ挙動
メッセージのユーザープロパティがフィルター式に完全一致配信される
メッセージのユーザープロパティが部分一致(AND条件未達成)配信されない
必須ユーザープロパティキーが存在しない配信されない
サブスクリプションにフィルター式がないトピック一致する全メッセージが配信される

次のステップ