トピック書き換え
多くのIoTデバイスは再設定やアップグレードに対応していないため、サブスクライブしているトピックを変更することが困難です。この問題を解決するために、EMQXはトピック書き換え機能を導入しました。関連するルールを設定することで、EMQXは新しいメッセージを送信するクライアントや新しいトピックをサブスクライブするクライアントのサブスクライブトピックを自動的に書き換えます。
このトピック書き換え機能は、保持メッセージや遅延パブリッシュ機能と組み合わせて利用できます。例えば、ユーザーが遅延パブリッシュを使用したい場合、トピック書き換えを使ってメッセージを必要なトピックにリダイレクトすることが可能です。
TIP
トピック書き換えは、書き換え前に認可チェックが実施されます。
TIP
トピック書き換えは、クライアントのサブスクライブ/アンサブスクライブ時に共有サブスクリプショントピックに関しては実際のトピックにのみ適用されます。つまり、共有サブスクリプショントピックのプレフィックス $share/<group-name>/ を除いた部分にのみ影響します。
例えば、クライアントが $share/group/t/1 のような共有サブスクリプショントピックフィルターをサブスクライブ/アンサブスクライブする場合、EMQXは $share/group/ を無視して t/1 のみをマッチングおよび書き換えの対象とします。
共有サブスクリプションの詳細については、共有サブスクリプションをご参照ください。
トピック書き換えルールの設定
EMQXのトピック書き換えルールは設定が必要です。複数のトピック書き換えルールを追加できます。ルール数に制限はありませんが、トピックを含むすべてのMQTTメッセージは再度書き換えルールにマッチングされる必要があります。
そのため、高スループット環境ではルール数に比例してパフォーマンスオーバーヘッドが発生しますので、この機能は慎重に利用してください。
各トピックの書き換えルールのフォーマットは以下の通りです。
rewrite = [
{
action: "all"
source_topic: "x/#"
dest_topic: "x/y/z/$1"
re: "^x/y/(.+)$"
}
]各書き換えルールはフィルターと正規表現で構成されます。
書き換えルールは publish、subscribe、および all の3種類に分かれています。publish ルールはPUBLISHメッセージに含まれるトピックにマッチし、subscribe ルールはSUBSCRIBEおよびUNSUBSCRIBEメッセージに含まれるトピックにマッチします。all ルールはPUBLISH、SUBSCRIBE、UNSUBSCRIBEメッセージに含まれるトピックすべてに有効です。
トピック書き換えが有効な状態で、PUBLISHメッセージなどのMQTTパケットを受信すると、EMQXはパケット内のトピックを使って設定ファイル内のルールのトピックフィルター部分と順にマッチングを試みます。マッチングに成功すると、正規表現を用いてトピック内の情報を抽出し、元のトピックを置換表現に置き換えて新しいトピックを生成します。
置換表現は $N 形式の変数を使って正規表現から抽出した要素を参照できます。$N の値は正規表現で抽出したN番目の要素を表し、例えば $1 は正規表現で抽出した最初の要素です。
また、置換表現では ${clientid} をクライアントID、${username} をクライアントのユーザー名として使用することも可能です。
注意点として、EMQXは設定ファイルの順番に従って書き換えルールを読み込みます。トピックが複数の書き換えルールのトピックフィルターに同時にマッチする場合、EMQXは最初にマッチしたルールでトピックを書き換えます。
もしルール内の正規表現がMQTTパケットのトピックにマッチしなかった場合、書き換えは失敗し、他のルールでの書き換えは行われません。したがって、MQTTパケットのトピックとトピック書き換えルールは慎重に設計する必要があります。
例
以下のトピック書き換えルールが設定ファイルに追加されているとします。
rewrite = [
{
action: "all"
source_topic: "y/+/z/#"
dest_topic: "y/z/$2"
re: "^y/(.+)/z/(.+)$"
}
{
action: "all"
source_topic: "x/#"
dest_topic: "z/y/x/$1"
re: "^x/y/(.+)$"
}
{
action: "all"
source_topic: "x/y/+"
dest_topic: "z/y/$1"
re: "^x/y/(\d+)$"
}
]このとき、以下の5つのトピックをサブスクライブするとします:y/a/z/b、y/def、x/1/2、x/y/2、および x/y/z。
y/defはいずれのトピックフィルターにもマッチしないため、トピック書き換えは行われず、そのままy/defトピックをサブスクライブします。y/a/z/bはy/+/z/#トピックフィルターにマッチし、EMQXは最初のルールを適用します。正規表現で[a、b]の要素を抽出し、2番目の要素をy/z/$2に代入して、実際にはy/z/bトピックをサブスクライブします。x/1/2はx/#トピックフィルターにマッチし、EMQXは2番目のルールを適用しますが、正規表現にマッチしないためトピック書き換えは行われず、実際にはx/1/2トピックをサブスクライブします。x/y/2はx/#とx/y/+の2つのトピックフィルターに同時にマッチします。EMQXは設定ファイルを上から順に読み込むため、3番目のルールを優先的に適用し、正規表現による置換を行い、実際にはz/y/2トピックをサブスクライブします。x/y/zもx/#とx/y/+の2つのトピックフィルターに同時にマッチしますが、3番目のルールの正規表現にマッチしないためトピック書き換えは行われず、実際にはx/y/zトピックをサブスクライブします。なお、3番目のルールの正規表現マッチが失敗しても、2番目のルールで再度マッチングは行われません。