ApsaraMQ for MQTT は、設定可能なルールを通じて、クライアントの接続および切断イベントをダウンストリームの Alibaba Cloud サービスにエクスポートします。バックエンドアプリケーションはこれらのイベントを利用して、接続ステータスを追跡したり、自動化ワークフローをトリガーしたり、接続パターンを分析したりします。
ステータスイベント通知は非同期であり、リアルタイムのクライアントステータスを反映するものではありません。クライアントの現在のステータスをリアルタイムで照会するには、「ApsaraMQ for MQTT クライアントのステータス取得」をご参照ください。
仕組み
ApsaraMQ for MQTT クライアントが接続または切断すると、ブローカーは設定されたルールに基づいて、ダウンストリームの Alibaba Cloud サービスにステータス通知をプッシュします。Elastic Compute Service (ECS) インスタンスにデプロイされたバックエンドアプリケーションは、これらの通知をサブスクライブして、クライアントのオンラインおよびオフライン遷移を検出します。

このプロセスは非同期であるため、単一の通知ではクライアントが現在オンラインであるかどうかは示されません。実際のステータスを判断するには、そのクライアントのイベント通知のタイムラインを分析します。詳細については、「イベントからのクライアントステータスの判断」をご参照ください。
利用シーン
ステータスイベントのエクスポートは、MQTT クライアントが接続または切断したときにバックエンドのアクションをトリガーします。接続アクティビティ分析の典型的なワークフローは次のとおりです。
クライアントの接続ステータスが複数回変更されます。
ブローカーは、設定されたルールに基づいて各変更を通知にカプセル化します。
通知は ApsaraMQ for RocketMQ のトピックに配信されます。
バックエンドアプリケーションは通知を利用し、クライアントの接続履歴を構築します。
制限事項
| 項目 | 制限 | 説明 |
|---|---|---|
| インスタンスあたりのルール数 | 100 | 上限の引き上げをリクエストするには、DingTalk グループ 116015007918 に参加して ApsaraMQ for MQTT のテクニカルサポートにご連絡ください。 |
| ルールの重複排除 | 内部リソースごとに各タイプのルールは 1 つ | 例えば、各グループは 1 つのクライアントステータス通知ルールをサポートし、各 ApsaraMQ for MQTT トピックは 1 つのデータインバウンドルールと 1 つのデータアウトバウンドルールをサポートします。 |
| リージョン間のルール | サポートされていません | データソースとデータ送信先は同じリージョンに存在する必要があります。 |
| ApsaraMQ for MQTT インスタンスのバージョン | カーネル V3.x.x のみ | ApsaraMQ for MQTT コンソールのインスタンスリストまたは [インスタンス詳細] ページでカーネルバージョンを確認してください。 |
| ApsaraMQ for RocketMQ インスタンスのバージョン | ApsaraMQ for RocketMQ 4.0 のみ | ApsaraMQ for MQTT と ApsaraMQ for RocketMQ 間のデータインバウンドルールおよびデータアウトバウンドルールに適用されます。 |
リソースマッピング
同じ ApsaraMQ for MQTT グループ内のすべてのクライアントのステータス通知は、同じダウンストリームリソースに転送されます。
| ApsaraMQ for MQTT リソース | Alibaba Cloud サービス | ダウンストリームリソース | パケット定義 |
|---|---|---|---|
| グループ | ApsaraMQ for RocketMQ | トピック | ApsaraMQ for MQTT と ApsaraMQ for RocketMQ 間のメッセージ構造のマッピング |
ステータスイベントエクスポートの設定
以下の手順では、ダウンストリームサービスとして ApsaraMQ for RocketMQ を使用します。
前提条件
開始する前に、以下を確認してください。
カーネルバージョンが V3.x.x の ApsaraMQ for MQTT インスタンス
同じリージョンにある ApsaraMQ for RocketMQ 4.0 インスタンス
ApsaraMQ for MQTT インスタンスに少なくとも 1 つのグループが設定されていること
ステップ 1:クライアントステータス通知ルールの作成
ApsaraMQ for MQTT コンソールでルールを作成し、クライアントステータスイベントをエクスポートしたいグループを選択します。詳細な手順については、「クライアントステータス通知ルールの作成」をご参照ください。
ステップ 2:バックエンドアプリケーションでステータス通知をサブスクライブする
ルールが有効になると、ステータスイベントは設定された ApsaraMQ for RocketMQ トピックに配信されます。イベントを受信するには、バックエンドアプリケーションでそのトピックをサブスクライブします。サブスクリプションの詳細については、「メッセージのサブスクライブ」をご参照ください。
イベントタイプ
各ステータス通知は、ApsaraMQ for RocketMQ メッセージとして配信されます。イベントタイプはメッセージタグで指定されます。
タグのフォーマット: connect、disconnect、または tcpclean
| タグ | 意味 | トリガー条件 |
|---|---|---|
connect | クライアントが接続しました | クライアントがブローカーとの接続を確立します。 |
disconnect | クライアントが DISCONNECT パケットを送信しました | MQTT プロトコルに従い、クライアントは TCP 接続を閉じる前に DISCONNECT パケットを送信します。クライアント SDK がこのパケットを送信しない場合、ブローカーは disconnect イベントを生成しません。 |
tcpclean | TCP 接続が閉じられました | クライアントが DISCONNECT パケットを送信したかどうかに関わらず、TCP 接続が閉じられます。 |
クライアントがオフラインであるかどうかを判断するには、disconnect ではなく tcpclean タグを確認してください。予期せず終了したクライアントは DISCONNECT パケットを送信しない可能性があるため、disconnect イベントが表示されない場合があります。
イベントデータ形式
メッセージ本文は、以下のフィールドを持つ JSON オブジェクトです。
| フィールド | タイプ | 説明 |
|---|---|---|
clientId | String | ApsaraMQ for MQTT のクライアント ID。フォーマット: GID_XXX@@@YYYYY。 |
time | Long | イベントが発生したときのタイムスタンプ。 |
eventType | String | イベントタイプ: connect、disconnect、または tcpclean。 |
channelId | String | TCP 接続の一意の識別子。 |
clientIp | String | MQTT クライアントのパブリック IP アドレスとポート。 |
例:
clientId: GID_XXX@@@YYYYY
time:1212121212
eventType:connect/disconnect/tcpclean
channelId:2b9b1281046046faafe5e0b458e4XXXX
clientIp:192.168.XX.XX:133XXイベントからのクライアントステータスの判断
通知は非同期であるため、単一のイベントからクライアントがオンラインであるかどうかを判断することはできません。各 clientId のイベントの完全なタイムラインを追跡し、以下のルールを適用してください。
順序付けにはタイムスタンプを使用します。
timeの値が大きいほど、より新しいイベントを意味します。同じclientIdを共有するイベント内でのみタイムスタンプを比較してください。オフラインイベントのスコープを
channelIdで限定します。 各channelIdは、正確に 1 つのconnectイベントと 1 つの close イベント (tcpclean) を持つ 1 つの TCP 接続を表します。tcpcleanイベントは、同じchannelId上の接続のみを無効にし、異なるchannelId上の接続には影響しません。一時的な再接続を処理します。 クライアントは複数回切断および再接続することがあり、複数の
channelId値を生成します。tcpcleanイベントを受信した場合は、クライアントをオフラインとしてマークする前に、そのchannelIdが追跡している接続と一致することを確認してください。
シナリオ例:
クライアントが接続し、短時間切断してから再接続します。
| 順序 | イベント | channelId | クライアントステータス |
|---|---|---|---|
| 1 | connect | aaa111 | オンライン (接続 aaa111 がアクティブ) |
| 2 | tcpclean | aaa111 | オフライン (接続 aaa111 がクローズ) |
| 3 | connect | bbb222 | オンライン (接続 bbb222 がアクティブ) |
aaa111 の tcpclean を bbb222 の connect の後に受信した場合、bbb222 には対応する tcpclean がないため、クライアントはまだオンラインです。
判断ロジック:
特定の clientId について:
1. channelId -> イベントのマップを維持します。
2. "connect" イベントを受信した場合:
- イベントをその channelId の下に保存します。
3. "tcpclean" イベントを受信した場合:
- イベントをその channelId の下に保存します。
- channelId に "connect" と "tcpclean" の両方のイベントが存在する場合、
その接続はクローズされています。マップから channelId を削除します。
4. クライアントがオンラインかどうかを確認します:
- マップ内のいずれかの channelId に "connect" イベントがあり、
"tcpclean" イベントがない場合、クライアントはオンラインです。
- すべての channelId が削除された場合 (または両方のイベントがある場合)、
クライアントはオフラインです。