すべてのプロダクト
Search
ドキュメントセンター

ApsaraMQ for MQTT:クライアント接続に関するよくある質問

最終更新日:Mar 05, 2026

このトピックでは、ApsaraMQ for MQTT クライアントをサーバーに接続する際に発生する一般的な問題について説明します。

Android デモでの「接続失敗」エラー

問題の説明

  • リソースは正しく構成されており、ネットワークにアクセスできます。

  • AccessKey ID と AccessKey Secret は認証されており、正しく入力されています。

考えられる原因

エンドポイントの形式が正しくありません。エンドポイントは、tcp://Endpoint:1883 または tls://Endpoint:8883 のいずれかの形式で指定してください。

クライアントは接続できるのに、サブスクリプション直後にコンシューマーが切断されるのはなぜですか?

考えられる原因:Topic 設定または命名形式が正しくありません。親 Topic とサブ Topic の構成を確認する必要があります。

  • 親 Topic

    • MQTT は、パブリッシュ/サブスクライブモデルに基づくメッセージングプロトコルです。各メッセージは 1 つの Topic に属します。MQTT はマルチレベル Topic をサポートしています。レベル 1 Topic は親 Topic と見なされます。ApsaraMQ for MQTT を使用する前に、コンソールで親 Topic を作成する必要があります。ApsaraMQ for MQTT コンソールまたは ApsaraMQ for RocketMQ コンソールで作成できます。

  • サブ Topic

    • レベル 2 またはレベル 3 Topic は、親 Topic のサブ Topic です。コンソールでサブ Topic を作成する必要はありません。コードで直接指定できます。親 Topic と各サブ Topic を区切るためにスラッシュ (/) を使用してサブ Topic に名前を付ける必要があります。例:<Parent topic name>/<Level-2 topic name>/<Level-3 topic name>。例:SendMessage/demo/producer。ApsaraMQ for MQTT では、親 Topic とサブ Topic の合計長は 64 文字を超えることはできません。この制限を超えると、クライアント例外が発生します。

コンソールに表示されるサブスクリプション数が、実際のシナリオで使用されるサブスクリプション数よりも多いのはなぜですか?

cleanSession パラメーターが false に設定されている場合、クライアントが切断された後でもサブスクリプションはクリアされません。

クライアントがオフラインになった後もサブスクリプションを保持したくない場合は、サブスクリプションクリーンアップ機能を使用して、オフラインクライアントのサブスクリプションを自動的にクリアしてください。

クライアントが切断と再接続を繰り返し、「invalid param」エラーを返す

考えられる原因:メッセージ本文のサイズが制限を超えたため、ブローカーが接続リクエストを拒否しました。ApsaraMQ for MQTT では、メッセージ本文のサイズは 64 KB を超えることはできません。

ビジネス側は変更されていないのに、クライアントとサーバーの接続が突然切断される

考えられる原因:

  • デバイスのシャットダウンまたはネットワーク接続の喪失により、クライアント接続が切断されます。

  • トークンベースの認証を使用している場合、トークンの有効期限が切れるとクライアントは切断されます。クライアントが再接続を試行する前に新しいトークンを取得できない場合、接続は失敗します。

クライアントのハートビートタイムアウト期間を指定する方法

MqttConnectOptions クラスを呼び出すことができます。

説明

サンプルコードを使用する前に、アクセス認証情報の環境変数を構成してください。環境変数の構成方法の詳細については、「アクセス認証情報の構成」をご参照ください。

ApsaraMQ for MQTT の AccessKey ID と AccessKey Secret の環境変数は、MQTT_AK_ENVMQTT_SK_ENV です。

String clientId = mqttTools.getClientId();
mqttConnectOptions = new MqttConnectOptions();
// An Alibaba Cloud account AccessKey has permissions to call all APIs. We recommend that you use a Resource Access Management (RAM) user for API calls and routine O&M.
// Do not store the AccessKey ID in your source code. Doing so may lead to credential leaks and compromise all resources under your account.
// This example stores the AccessKey in an environment variable.
mqttConnectOptions.setUserName("Signature|" + System.getenv("MQTT_AK_ENV") + "|" + instanceId);
mqttConnectOptions.setPassword(mqttTools.macSignature(clientId).toCharArray());
mqttConnectOptions.setCleanSession(true);
// The heartbeat timeout period of the client. Default value: 90 seconds.
mqttConnectOptions.setKeepAliveInterval(90);
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setMqttVersion(MQTT_VERSION_3_1_1);
mqttConnectOptions.setConnectionTimeout(5000);
mqttLogger.info("MQTT is connect setting={},clientId={}", JSON.toJSONString(mqttConnectOptions), clientId);
mqttClient = new MqttClient("tcp://" + endPoint + ":1883", clientId, memoryPersistence);
mqttClient.setTimeToWait(5000);
mqttClient.setCallback(this.getMqttCallbackExtended());
mqttClient.connect(mqttConnectOptions);

クライアント接続時に「valid owner failed」エラーが発生する

次の項目を確認する必要があります。

  • インスタンス名は正しく指定されていますか?

  • コンソールでグループと Topic を作成し、それらの名前を正しく指定しましたか?

  • 選択したインスタンスに対してグループまたは Topic を正しく指定しましたか?

デバイスで「connection reset by peer」エラーが時折発生する

クライアント ID (ClientID) の値が重複すると、クライアント同士が互いに切断し、サーバーが接続を閉じます。クライアントが TCP 接続を介してデータを送信し続けると、ピアソケットが RST パケットを送信する原因となります。

指定するクライアント ID がグローバルに一意であることを確認する必要があります。詳細については、「クライアントの制限」をご参照ください。

Message Queue for MQTT の Java SDK クライアントで自動接続機能を構成する方法

Java SDK クライアントの自動再接続機能を有効にする

mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(true);

autoReconnect パラメーターを true に設定すると、ApsaraMQ for MQTT の Java SDK クライアントは自動的に再接続します。

mqttClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                /**
                 * クライアント接続が確立された後にサブスクライブする必要がある Topic。
                 */
                System.out.println("connect success");
            }

            @Override
            public void connectionLost(Throwable throwable) {
                throwable.printStackTrace();
            }

            @Override
            public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                /**
                 * メッセージを消費するために呼び出されるコールバック。コールバックが例外をスローしないことを確認してください。コールバックが返されると、メッセージは消費されます。
                 * メッセージは指定された時間内に消費する必要があります。消費がブローカーによって設定されたタイムアウト期間よりも長くかかる場合、ブローカーは信頼性の高い送信モードでメッセージを再送する可能性があります。ビジネスロジックが重複を処理することを確認してください。
                 * タイムアウト期間の詳細については、「制限」をご参照ください。
                 */
                System.out.println(
                    "receive msg from topic " + s + " , body is " + new String(mqttMessage.getPayload()));

            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                System.out.println("send msg succeed topic is : " + iMqttDeliveryToken.getTopics()[0]);
            }
});

クライアントコールバックの connectComplete メソッドが呼び出されると、接続または再接続が成功します。接続ステータスを監視する必要はありません。再確立された接続は以前の接続とは異なります。したがって、以前の接続でのメッセージの送信やサブスクライブなどの操作は有効になりません。

この時点で、ビジネス側が新しい内部接続を介してサブスクリプションメッセージを送信し続けることができるように、Topic を再サブスクライブする必要があります。

@Override
public void connectComplete(boolean reconnect, String serverURI) {
    /**
    * クライアント接続が確立された後にサブスクライブする必要がある Topic。
    */
    System.out.println("connect success");
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                final String topicFilter[] = {mq4IotTopic};
                final int[] qos = {qosLevel};
                mqttClient.subscribe(topicFilter, qos);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    });
}

アプリケーション側でのクライアント接続の手動メンテナンス

mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setAutomaticReconnect(false);

autoReconnect パラメーターが false に設定されている場合、ApsaraMQ for MQTT クライアントは切断後に自動的に再接続しません。

接続が失われると、ビジネス側で異常な状態が検出されます。レガシー接続を手動でシャットダウンし、新しい接続を確立する必要があります。