ApsaraMQ for MQTT では、同期クエリを実行するか、非同期ステータス通知をサブスクライブして、ApsaraMQ for MQTT クライアントのステータスを取得できます。このトピックでは、2 つの方法の動作メカニズム、シナリオ、および実装方法について説明します。また、2 つの方法の違いについても説明します。
動作メカニズム
ApsaraMQ for MQTT ブローカーでは、次の方法を使用して ApsaraMQ for MQTT クライアントのステータスを取得できます。
同期クエリ
この方法は比較的簡単です。パブリックエンドポイントを使用して HTTP または HTTPS リクエストを開始し、API オペレーションを呼び出して、特定のクライアントのステータスをクエリできます。また、この方法を使用して、一度に複数のクライアントのステータスをクエリすることもできます。
非同期ステータス通知
これは通知ベースの方法です。ApsaraMQ for MQTT クライアントがオンラインまたはオフラインになると、ApsaraMQ for MQTT ブローカーは、Alibaba Cloud サーバーにデプロイされているバックエンドサービスアプリケーションにステータス変更イベントに関する通知を送信します。
この方法は非同期プロセスであり、リアルタイムの情報は提供されません。アプリケーションは、イベント通知のタイムラインに基づいてのみ、クライアントの実際のステータスを判断できます。
シナリオ
上記の 2 つの方法は、次のシナリオに適しています。
同期クエリ
後続の操作ロジックは、メインサービスプロセス中に特定の ApsaraMQ for MQTT クライアントがオンラインかどうかによって異なります。
O&M エンジニアは、特定の ApsaraMQ for MQTT クライアントがオンラインかどうかを判断する必要があります。
非同期ステータス通知
特定の ApsaraMQ for MQTT クライアントがオンラインまたはオフラインになったときに、ApsaraMQ for MQTT ブローカーが特定の事前定義アクションをトリガーする必要があります。
ApsaraMQ for MQTT ブローカーは、特定の ApsaraMQ for MQTT クライアントのステータス変更イベントに記録されたデータを収集および分析し、イベントに基づいて通知を送信する必要があります。
同期クエリと非同期ステータス通知の違い
次の項目では、2 つの方法の違いについて説明します。
同期クエリを実行して、特定の ApsaraMQ for MQTT クライアントのリアルタイムステータスをクエリできます。この方法は、理論的には非同期ステータス通知よりも正確です。
同期クエリと比較して、非同期ステータス通知は、メッセージのデカップリングが使用されるため、ApsaraMQ for MQTT クライアントの実際のステータスを判断する際に、より複雑で精度が低くなります。ただし、この方法を使用して、複数の ApsaraMQ for MQTT クライアントのステータスのトレースを分析できます。この方法を使用して、多数の ApsaraMQ for MQTT クライアントのステータスに関する統計を収集できます。
実装方法
同期クエリ
次のオペレーションを呼び出して、1 つ以上のクライアントのステータスをクエリできます。
非同期ステータス通知
ApsaraMQ for MQTT が提供するクラウド SDK を呼び出して、ApsaraMQ for MQTT クライアントのステータス通知を取得できます。クラウド SDK のダウンロード方法については、リリースノートをご参照ください。
次のサンプルコードは、ApsaraMQ for MQTT クライアントのステータス通知を取得する方法の例を示しています。
package com.aliyun.openservices.lmq.example; import com.alibaba.fastjson.JSONObject; import com.alibaba.mqtt.server.ServerConsumer; import com.alibaba.mqtt.server.callback.StatusListener; import com.alibaba.mqtt.server.config.ChannelConfig; import com.alibaba.mqtt.server.config.ConsumerConfig; import com.alibaba.mqtt.server.model.StatusNotice; public class MQTTClientStatusNoticeProcessDemo { public static void main(String[] args) throws Exception { /** * 作成した Message Queue for MQTT インスタンスのエンドポイント。 * クラウド SDK を使用してインスタンスにアクセスするために使用するエンドポイントを取得するには、テクニカルサポートにお問い合わせください。 * エンドポイントとして IP アドレスではなくドメイン名を使用してください。そうしないと、ブローカーの例外が発生する可能性があります。 */ String domain = "domain"; /** * クラウド SDK が使用するポート。クラウド SDK が使用するプロトコルとポートは一致する必要があります。値を 5672 に設定します。 */ int port = 5672; /** * 作成した Message Queue for MQTT インスタンスの ID。 */ String instanceId = "instanceId"; /** * ID 認証のために Alibaba Cloud RAM コンソールで作成した AccessKey ID。AccessKey ID の取得方法については、「AccessKey ペアの取得」をご参照ください。 */ String accessKey = "accessKey"; /** * ID 認証のために Alibaba Cloud RAM コンソールで作成した AccessKey シークレット。AccessKey シークレットは、署名認証モードを使用する場合にのみ必要です。AccessKey シークレットの取得方法については、「AccessKey ペアの取得」をご参照ください。 */ String secretKey = "secretKey"; /** * Message Queue for MQTT コンソールで作成したグループの ID。 * */ String mqttGroupId = "mqttGroupId"; ChannelConfig channelConfig = new ChannelConfig(); channelConfig.setDomain(domain); channelConfig.setPort(port); channelConfig.setInstanceId(instanceId); channelConfig.setAccessKey(accessKey); channelConfig.setSecretKey(secretKey); ServerConsumer serverConsumer = new ServerConsumer(channelConfig, new ConsumerConfig()); serverConsumer.start(); serverConsumer.subscribeStatus(mqttGroupId, new StatusListener() { @Override public void process(StatusNotice statusNotice) { System.out.println(JSONObject.toJSONString(statusNotice)); } }); } }