サブスクリプションフィルターの使い方
このページでは、EMQXでサブスクリプションフィルター機能を有効化し、実際に動作を確認する手順を説明します。MQTTX CLIを使ってパブリッシャーと複数のサブスクライバーをシミュレートし、フィルター式がどのように各サブスクライバーに届くメッセージを制御するかを観察します。
前提条件
開始する前に、以下を準備してください。
- EMQX 6.2以上が稼働していること
- MQTTX CLI がインストールされていること
ステップ1:サブスクリプションフィルターを有効化する
サブスクリプションフィルターはデフォルトで無効になっています。無効時は、?文字はトピック文字列の通常の一部として扱われ、既存のサブスクリプションとの完全な互換性が保たれます。
ダッシュボードからの設定
- Management -> MQTT Settings -> General タブに移動します。
- Subscription Message Filter フィールドを enable に設定します。
- Save Changes をクリックします。
変更はブローカーの再起動なしに即時反映されます。
設定ファイルからの設定
emqx.conf に以下を追加します。
mqtt.subscription_message_filter = enable変更を反映するにはEMQXを再起動するか、デプロイ環境が対応していれば設定のリロードを行ってください。
REST APIからの設定
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-roomA | sensor/+/temperature?location=roomA | location=roomA |
sub-roomB | sensor/+/temperature?location=roomB | location=roomB |
sub-all | sensor/+/temperature | 全メッセージ(フィルターなし) |
3つのターミナルを開き、それぞれのサブスクライバーを起動します。
ターミナル1:roomAサブスクライバー
mqttx sub -h localhost -p 1883 \
--mqtt-version 5 \
--client-id sub-roomA \
-t "sensor/+/temperature?location=roomA"ターミナル2:roomBサブスクライバー
mqttx sub -h localhost -p 1883 \
--mqtt-version 5 \
--client-id sub-roomB \
-t "sensor/+/temperature?location=roomB"ターミナル3:フィルターなしサブスクライバー
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 を含むメッセージをパブリッシュします。
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向けのメッセージをパブリッシュする
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論理)のテスト
サブスクリプションフィルターは & で複数条件を結合できます。location と unit の両方が一致する必要がある新しいサブスクライバーを起動します。
mqttx sub -h localhost -p 1883 \
--mqtt-version 5 \
--client-id sub-roomA-celsius \
-t "sensor/+/temperature?location=roomA&unit=celsius"両条件を満たすメッセージをパブリッシュします。
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 が不一致のメッセージをパブリッシュします。
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:ユーザープロパティなしのメッセージをパブリッシュする
ユーザープロパティなしのメッセージをパブリッシュします。
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条件未達成) | 配信されない |
| 必須ユーザープロパティキーが存在しない | 配信されない |
| サブスクリプションにフィルター式がない | トピック一致する全メッセージが配信される |
次のステップ
- サブスクリプションフィルター概要:設計、概念、ユースケースを詳しく理解する。
- ワイルドカードサブスクリプション:ワイルドカートピックフィルターとサブスクリプションフィルターを組み合わせて柔軟なルーティングを実現する。